├── NFTCollection.sol ├── Part2-NFT-Market-Resell-Contract └── N2D-Market-NFT-Resell-SmartContract.sol ├── Part3-NextJS-Market-WebFrontEnd ├── _app.js ├── engine │ ├── NFTCollection.json │ ├── Resell.json │ └── configuration.js ├── index.js └── portal.js ├── Part4-RelistNFT-Buy-Sell ├── _app.js ├── engine │ ├── NFTCollection.json │ ├── Resell.json │ └── configuration.js ├── footer.js ├── hardhat.config.js ├── index.js ├── portal.js └── public │ ├── bsc.png │ ├── chainagnostic.png │ ├── discord.png │ ├── discordlogo.PNG │ ├── ethereumlogo.png │ ├── n2DMarket.png │ ├── n2dr-logo.png │ ├── polygonwhite.png │ ├── twitter.png │ ├── web3logo.png │ └── youtube.png ├── Part5-Create-and-Sell-NFT-App ├── Market.json ├── N2D-Market-CreateNFT-SmartContract.sol ├── N2D-Market-SellCreatedNFT-SmartContract.sol ├── NFT.json ├── _app.js ├── create.js ├── index.js └── portal.js ├── Part6-Final-Multichain-Integration ├── engine │ ├── chainchange.js │ ├── configuration.js │ └── connectchain.js └── pages │ ├── _app.js │ ├── create.js │ ├── index.js │ └── portal.js ├── README.md └── n2DMarket.png /NFTCollection.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT LICENSE 2 | 3 | /* 4 | N2D NFT ERC721 NFT Smart Contract. 5 | 6 | Follow/Subscribe Youtube, Github, IM, Tiktok 7 | for more amazing content!! 8 | @Net2Dev 9 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗ 10 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║ 11 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝ 12 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░ 13 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░ 14 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░ 15 | 16 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL 17 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE 18 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY 19 | OTHER USE. THIS IS TRAINING/EDUCATIONAL 20 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE 21 | TERMS SPECIFIED ABOVE. 22 | */ 23 | 24 | 25 | import "@openzeppelin/contracts/access/Ownable.sol"; 26 | import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; 27 | 28 | pragma solidity ^0.8.4; 29 | 30 | contract Collection is ERC721Enumerable, Ownable { 31 | 32 | 33 | using Strings for uint256; 34 | string public baseURI; 35 | string public baseExtension = ".json"; 36 | uint256 public maxSupply = 1000; 37 | uint256 public maxMintAmount = 5; 38 | bool public paused = false; 39 | 40 | constructor() ERC721("Net2Dev NFT Collection", "N2D") {} 41 | 42 | 43 | function _baseURI() internal view virtual override returns (string memory) { 44 | return "ipfs://QmYB5uWZqfunBq7yWnamTqoXWBAHiQoirNLmuxMzDThHhi/"; 45 | 46 | } 47 | 48 | function mint(address _to, uint256 _mintAmount) public payable { 49 | uint256 supply = totalSupply(); 50 | require(!paused); 51 | require(_mintAmount > 0); 52 | require(_mintAmount <= maxMintAmount); 53 | require(supply + _mintAmount <= maxSupply); 54 | 55 | for (uint256 i = 1; i <= _mintAmount; i++) { 56 | _safeMint(_to, supply + i); 57 | } 58 | } 59 | 60 | 61 | function walletOfOwner(address _owner) 62 | public 63 | view 64 | returns (uint256[] memory) 65 | { 66 | uint256 ownerTokenCount = balanceOf(_owner); 67 | uint256[] memory tokenIds = new uint256[](ownerTokenCount); 68 | for (uint256 i; i < ownerTokenCount; i++) { 69 | tokenIds[i] = tokenOfOwnerByIndex(_owner, i); 70 | } 71 | return tokenIds; 72 | } 73 | 74 | 75 | function tokenURI(uint256 tokenId) 76 | public 77 | view 78 | virtual 79 | override 80 | returns (string memory) { 81 | require( 82 | _exists(tokenId), 83 | "ERC721Metadata: URI query for nonexistent token" 84 | ); 85 | 86 | string memory currentBaseURI = _baseURI(); 87 | return 88 | bytes(currentBaseURI).length > 0 89 | ? string(abi.encodePacked(currentBaseURI, tokenId.toString(), baseExtension)) 90 | : ""; 91 | } 92 | // only owner 93 | 94 | function setmaxMintAmount(uint256 _newmaxMintAmount) public onlyOwner() { 95 | maxMintAmount = _newmaxMintAmount; 96 | } 97 | 98 | function setBaseURI(string memory _newBaseURI) public onlyOwner() { 99 | baseURI = _newBaseURI; 100 | } 101 | 102 | function setBaseExtension(string memory _newBaseExtension) public onlyOwner() { 103 | baseExtension = _newBaseExtension; 104 | } 105 | 106 | function pause(bool _state) public onlyOwner() { 107 | paused = _state; 108 | } 109 | 110 | function withdraw() public payable onlyOwner() { 111 | require(payable(msg.sender).send(address(this).balance)); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /Part2-NFT-Market-Resell-Contract/N2D-Market-NFT-Resell-SmartContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT LICENSE 2 | 3 | /* 4 | Follow/Subscribe Youtube, Github, IM, Tiktok 5 | for more amazing content!! 6 | @Net2Dev 7 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗ 8 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║ 9 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝ 10 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░ 11 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░ 12 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░ 13 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL 14 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE 15 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY 16 | OTHER USE. THIS IS TRAINING/EDUCATIONAL 17 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE 18 | TERMS SPECIFIED ABOVE. 19 | 20 | Revised v2 21 | 22 | - Added Cancel Sale Function 23 | - Fixed ItemId to TokenId Conflict Bug 24 | using tokenId as location in Memory in Struct 25 | 26 | Revised v3 27 | 28 | - Added Listing Fee Balance Withdraw Function 29 | 30 | */ 31 | 32 | 33 | 34 | pragma solidity 0.8.4; 35 | 36 | import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; 37 | import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; 38 | import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; 39 | import "@openzeppelin/contracts/access/Ownable.sol"; 40 | 41 | contract NFTMarketResell is IERC721Receiver, ReentrancyGuard, Ownable { 42 | 43 | address payable holder; 44 | uint256 listingFee = 0.0025 ether; 45 | 46 | struct List { 47 | uint256 tokenId; 48 | address payable seller; 49 | address payable holder; 50 | uint256 price; 51 | bool sold; 52 | } 53 | 54 | mapping(uint256 => List) public vaultItems; 55 | 56 | event NFTListCreated ( 57 | uint256 indexed tokenId, 58 | address seller, 59 | address holder, 60 | uint256 price, 61 | bool sold 62 | ); 63 | 64 | function getListingFee() public view returns (uint256) { 65 | return listingFee; 66 | } 67 | 68 | ERC721Enumerable nft; 69 | 70 | constructor(ERC721Enumerable _nft) { 71 | holder = payable(msg.sender); 72 | nft = _nft; 73 | } 74 | 75 | function listSale(uint256 tokenId, uint256 price) public payable nonReentrant { 76 | require(nft.ownerOf(tokenId) == msg.sender, "NFT not yours"); 77 | require(vaultItems[tokenId].tokenId == 0, "NFT already listed"); 78 | require(price > 0, "Amount must be higher than 0"); 79 | require(msg.value == listingFee, "Please transfer 0.0025 crypto to pay listing fee"); 80 | vaultItems[tokenId] = List(tokenId, payable(msg.sender), payable(address(this)), price, false); 81 | nft.transferFrom(msg.sender, address(this), tokenId); 82 | emit NFTListCreated(tokenId, msg.sender, address(this), price, false); 83 | } 84 | 85 | function buyNft(uint256 tokenId) public payable nonReentrant { 86 | uint256 price = vaultItems[tokenId].price; 87 | require(msg.value == price, "Transfer Total Amount to complete transaction"); 88 | vaultItems[tokenId].seller.transfer(msg.value); 89 | nft.transferFrom(address(this), msg.sender, tokenId); 90 | vaultItems[tokenId].sold = true; 91 | delete vaultItems[tokenId]; 92 | } 93 | 94 | function cancelSale(uint256 tokenId) public nonReentrant { 95 | require(vaultItems[tokenId].seller == msg.sender, "NFT not yours"); 96 | nft.transferFrom(address(this), msg.sender, tokenId); 97 | delete vaultItems[tokenId]; 98 | } 99 | 100 | function getPrice(uint256 tokenId) public view returns (uint256) { 101 | uint256 price = vaultItems[tokenId].price; 102 | return price; 103 | } 104 | 105 | function nftListings() public view returns (List[] memory) { 106 | uint256 nftCount = nft.totalSupply(); 107 | uint currentIndex = 0; 108 | List[] memory items = new List[](nftCount); 109 | for (uint i = 0; i < nftCount; i++) { 110 | if (vaultItems[i + 1].holder == address(this)) { 111 | uint currentId = i + 1; 112 | List storage currentItem = vaultItems[currentId]; 113 | items[currentIndex] = currentItem; 114 | currentIndex += 1; 115 | } 116 | } 117 | return items; 118 | } 119 | 120 | function onERC721Received( 121 | address, 122 | address from, 123 | uint256, 124 | bytes calldata 125 | ) external pure override returns (bytes4) { 126 | require(from == address(0x0), "Cannot send nfts to Vault directly"); 127 | return IERC721Receiver.onERC721Received.selector; 128 | } 129 | 130 | function withdraw() public payable onlyOwner() { 131 | require(payable(msg.sender).send(address(this).balance)); 132 | } 133 | 134 | } 135 | -------------------------------------------------------------------------------- /Part3-NextJS-Market-WebFrontEnd/_app.js: -------------------------------------------------------------------------------- 1 | import { createTheme, NextUIProvider } from "@nextui-org/react"; 2 | import 'sf-font'; 3 | import Link from 'next/link' 4 | import { Spacer, Button, Col, Row, Container, Dropdown } from '@nextui-org/react'; 5 | import react from "react"; 6 | 7 | const theme = createTheme({ 8 | type: "dark", 9 | theme: { 10 | fontFamily:'SF Pro Display', 11 | colors: { 12 | primaryLight: '$blue200', 13 | primaryLightHover: '$blue300', 14 | primaryLightActive: '$blue400', 15 | primaryLightContrast: '$blue600', 16 | primary: '$purple500', 17 | primaryBorder: '$blue500', 18 | primaryBorderHover: '$blue600', 19 | primarySolidHover: '$blue700', 20 | primarySolidContrast: '$white', 21 | primaryShadow: '$white500', 22 | transparent: '#00000000', 23 | 24 | gradient: 'linear-gradient(112deg, $blue100 -25%, $pink500 -10%, $purple300 90%)', 25 | link: '#5E1DAD', 26 | 27 | myColor: '#00000030' 28 | 29 | }, 30 | space: {}, 31 | fonts: {} 32 | } 33 | }) 34 | 35 | function MyApp({ Component, pageProps }) { 36 | 37 | return( 38 |
39 |
40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 57 | 58 | 59 | 60 | 61 | 71 | 72 | 73 | 74 | 87 | 88 | 89 | 90 | 91 | 92 | 93 |
94 |
95 | 96 | ) 97 | 98 | 99 | } 100 | 101 | export default MyApp 102 | -------------------------------------------------------------------------------- /Part3-NextJS-Market-WebFrontEnd/engine/NFTCollection.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "owner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "approved", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "Approval", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "owner", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "operator", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "bool", 45 | "name": "approved", 46 | "type": "bool" 47 | } 48 | ], 49 | "name": "ApprovalForAll", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "previousOwner", 59 | "type": "address" 60 | }, 61 | { 62 | "indexed": true, 63 | "internalType": "address", 64 | "name": "newOwner", 65 | "type": "address" 66 | } 67 | ], 68 | "name": "OwnershipTransferred", 69 | "type": "event" 70 | }, 71 | { 72 | "anonymous": false, 73 | "inputs": [ 74 | { 75 | "indexed": true, 76 | "internalType": "address", 77 | "name": "from", 78 | "type": "address" 79 | }, 80 | { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "to", 84 | "type": "address" 85 | }, 86 | { 87 | "indexed": true, 88 | "internalType": "uint256", 89 | "name": "tokenId", 90 | "type": "uint256" 91 | } 92 | ], 93 | "name": "Transfer", 94 | "type": "event" 95 | }, 96 | { 97 | "inputs": [ 98 | { 99 | "internalType": "contract IERC20", 100 | "name": "_paytoken", 101 | "type": "address" 102 | }, 103 | { 104 | "internalType": "uint256", 105 | "name": "_costvalue", 106 | "type": "uint256" 107 | } 108 | ], 109 | "name": "addCurrency", 110 | "outputs": [], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "address", 118 | "name": "to", 119 | "type": "address" 120 | }, 121 | { 122 | "internalType": "uint256", 123 | "name": "tokenId", 124 | "type": "uint256" 125 | } 126 | ], 127 | "name": "approve", 128 | "outputs": [], 129 | "stateMutability": "nonpayable", 130 | "type": "function" 131 | }, 132 | { 133 | "inputs": [ 134 | { 135 | "internalType": "address", 136 | "name": "_to", 137 | "type": "address" 138 | }, 139 | { 140 | "internalType": "uint256", 141 | "name": "_mintAmount", 142 | "type": "uint256" 143 | } 144 | ], 145 | "name": "mint", 146 | "outputs": [], 147 | "stateMutability": "payable", 148 | "type": "function" 149 | }, 150 | { 151 | "inputs": [ 152 | { 153 | "internalType": "address", 154 | "name": "_to", 155 | "type": "address" 156 | }, 157 | { 158 | "internalType": "uint256", 159 | "name": "_mintAmount", 160 | "type": "uint256" 161 | }, 162 | { 163 | "internalType": "uint256", 164 | "name": "_pid", 165 | "type": "uint256" 166 | } 167 | ], 168 | "name": "mintpid", 169 | "outputs": [], 170 | "stateMutability": "payable", 171 | "type": "function" 172 | }, 173 | { 174 | "inputs": [ 175 | { 176 | "internalType": "bool", 177 | "name": "_state", 178 | "type": "bool" 179 | } 180 | ], 181 | "name": "pause", 182 | "outputs": [], 183 | "stateMutability": "nonpayable", 184 | "type": "function" 185 | }, 186 | { 187 | "inputs": [], 188 | "name": "renounceOwnership", 189 | "outputs": [], 190 | "stateMutability": "nonpayable", 191 | "type": "function" 192 | }, 193 | { 194 | "inputs": [ 195 | { 196 | "internalType": "address", 197 | "name": "from", 198 | "type": "address" 199 | }, 200 | { 201 | "internalType": "address", 202 | "name": "to", 203 | "type": "address" 204 | }, 205 | { 206 | "internalType": "uint256", 207 | "name": "tokenId", 208 | "type": "uint256" 209 | } 210 | ], 211 | "name": "safeTransferFrom", 212 | "outputs": [], 213 | "stateMutability": "nonpayable", 214 | "type": "function" 215 | }, 216 | { 217 | "inputs": [ 218 | { 219 | "internalType": "address", 220 | "name": "from", 221 | "type": "address" 222 | }, 223 | { 224 | "internalType": "address", 225 | "name": "to", 226 | "type": "address" 227 | }, 228 | { 229 | "internalType": "uint256", 230 | "name": "tokenId", 231 | "type": "uint256" 232 | }, 233 | { 234 | "internalType": "bytes", 235 | "name": "_data", 236 | "type": "bytes" 237 | } 238 | ], 239 | "name": "safeTransferFrom", 240 | "outputs": [], 241 | "stateMutability": "nonpayable", 242 | "type": "function" 243 | }, 244 | { 245 | "inputs": [ 246 | { 247 | "internalType": "address", 248 | "name": "operator", 249 | "type": "address" 250 | }, 251 | { 252 | "internalType": "bool", 253 | "name": "approved", 254 | "type": "bool" 255 | } 256 | ], 257 | "name": "setApprovalForAll", 258 | "outputs": [], 259 | "stateMutability": "nonpayable", 260 | "type": "function" 261 | }, 262 | { 263 | "inputs": [ 264 | { 265 | "internalType": "string", 266 | "name": "_newBaseExtension", 267 | "type": "string" 268 | } 269 | ], 270 | "name": "setBaseExtension", 271 | "outputs": [], 272 | "stateMutability": "nonpayable", 273 | "type": "function" 274 | }, 275 | { 276 | "inputs": [ 277 | { 278 | "internalType": "string", 279 | "name": "_newBaseURI", 280 | "type": "string" 281 | } 282 | ], 283 | "name": "setBaseURI", 284 | "outputs": [], 285 | "stateMutability": "nonpayable", 286 | "type": "function" 287 | }, 288 | { 289 | "inputs": [ 290 | { 291 | "internalType": "uint256", 292 | "name": "_newmaxMintAmount", 293 | "type": "uint256" 294 | } 295 | ], 296 | "name": "setmaxMintAmount", 297 | "outputs": [], 298 | "stateMutability": "nonpayable", 299 | "type": "function" 300 | }, 301 | { 302 | "inputs": [ 303 | { 304 | "internalType": "address", 305 | "name": "from", 306 | "type": "address" 307 | }, 308 | { 309 | "internalType": "address", 310 | "name": "to", 311 | "type": "address" 312 | }, 313 | { 314 | "internalType": "uint256", 315 | "name": "tokenId", 316 | "type": "uint256" 317 | } 318 | ], 319 | "name": "transferFrom", 320 | "outputs": [], 321 | "stateMutability": "nonpayable", 322 | "type": "function" 323 | }, 324 | { 325 | "inputs": [ 326 | { 327 | "internalType": "address", 328 | "name": "newOwner", 329 | "type": "address" 330 | } 331 | ], 332 | "name": "transferOwnership", 333 | "outputs": [], 334 | "stateMutability": "nonpayable", 335 | "type": "function" 336 | }, 337 | { 338 | "inputs": [], 339 | "name": "withdraw", 340 | "outputs": [], 341 | "stateMutability": "payable", 342 | "type": "function" 343 | }, 344 | { 345 | "inputs": [ 346 | { 347 | "internalType": "uint256", 348 | "name": "_pid", 349 | "type": "uint256" 350 | } 351 | ], 352 | "name": "withdrawcustom", 353 | "outputs": [], 354 | "stateMutability": "payable", 355 | "type": "function" 356 | }, 357 | { 358 | "inputs": [], 359 | "stateMutability": "nonpayable", 360 | "type": "constructor" 361 | }, 362 | { 363 | "inputs": [ 364 | { 365 | "internalType": "uint256", 366 | "name": "", 367 | "type": "uint256" 368 | } 369 | ], 370 | "name": "AllowedCrypto", 371 | "outputs": [ 372 | { 373 | "internalType": "contract IERC20", 374 | "name": "paytoken", 375 | "type": "address" 376 | }, 377 | { 378 | "internalType": "uint256", 379 | "name": "costvalue", 380 | "type": "uint256" 381 | } 382 | ], 383 | "stateMutability": "view", 384 | "type": "function" 385 | }, 386 | { 387 | "inputs": [ 388 | { 389 | "internalType": "address", 390 | "name": "owner", 391 | "type": "address" 392 | } 393 | ], 394 | "name": "balanceOf", 395 | "outputs": [ 396 | { 397 | "internalType": "uint256", 398 | "name": "", 399 | "type": "uint256" 400 | } 401 | ], 402 | "stateMutability": "view", 403 | "type": "function" 404 | }, 405 | { 406 | "inputs": [], 407 | "name": "baseExtension", 408 | "outputs": [ 409 | { 410 | "internalType": "string", 411 | "name": "", 412 | "type": "string" 413 | } 414 | ], 415 | "stateMutability": "view", 416 | "type": "function" 417 | }, 418 | { 419 | "inputs": [], 420 | "name": "baseURI", 421 | "outputs": [ 422 | { 423 | "internalType": "string", 424 | "name": "", 425 | "type": "string" 426 | } 427 | ], 428 | "stateMutability": "view", 429 | "type": "function" 430 | }, 431 | { 432 | "inputs": [], 433 | "name": "cost", 434 | "outputs": [ 435 | { 436 | "internalType": "uint256", 437 | "name": "", 438 | "type": "uint256" 439 | } 440 | ], 441 | "stateMutability": "view", 442 | "type": "function" 443 | }, 444 | { 445 | "inputs": [ 446 | { 447 | "internalType": "uint256", 448 | "name": "tokenId", 449 | "type": "uint256" 450 | } 451 | ], 452 | "name": "getApproved", 453 | "outputs": [ 454 | { 455 | "internalType": "address", 456 | "name": "", 457 | "type": "address" 458 | } 459 | ], 460 | "stateMutability": "view", 461 | "type": "function" 462 | }, 463 | { 464 | "inputs": [ 465 | { 466 | "internalType": "uint256", 467 | "name": "_pid", 468 | "type": "uint256" 469 | } 470 | ], 471 | "name": "getCryptotoken", 472 | "outputs": [ 473 | { 474 | "internalType": "contract IERC20", 475 | "name": "", 476 | "type": "address" 477 | } 478 | ], 479 | "stateMutability": "view", 480 | "type": "function" 481 | }, 482 | { 483 | "inputs": [ 484 | { 485 | "internalType": "uint256", 486 | "name": "_pid", 487 | "type": "uint256" 488 | } 489 | ], 490 | "name": "getNFTCost", 491 | "outputs": [ 492 | { 493 | "internalType": "uint256", 494 | "name": "", 495 | "type": "uint256" 496 | } 497 | ], 498 | "stateMutability": "view", 499 | "type": "function" 500 | }, 501 | { 502 | "inputs": [ 503 | { 504 | "internalType": "address", 505 | "name": "owner", 506 | "type": "address" 507 | }, 508 | { 509 | "internalType": "address", 510 | "name": "operator", 511 | "type": "address" 512 | } 513 | ], 514 | "name": "isApprovedForAll", 515 | "outputs": [ 516 | { 517 | "internalType": "bool", 518 | "name": "", 519 | "type": "bool" 520 | } 521 | ], 522 | "stateMutability": "view", 523 | "type": "function" 524 | }, 525 | { 526 | "inputs": [], 527 | "name": "maxMintAmount", 528 | "outputs": [ 529 | { 530 | "internalType": "uint256", 531 | "name": "", 532 | "type": "uint256" 533 | } 534 | ], 535 | "stateMutability": "view", 536 | "type": "function" 537 | }, 538 | { 539 | "inputs": [], 540 | "name": "maxSupply", 541 | "outputs": [ 542 | { 543 | "internalType": "uint256", 544 | "name": "", 545 | "type": "uint256" 546 | } 547 | ], 548 | "stateMutability": "view", 549 | "type": "function" 550 | }, 551 | { 552 | "inputs": [], 553 | "name": "name", 554 | "outputs": [ 555 | { 556 | "internalType": "string", 557 | "name": "", 558 | "type": "string" 559 | } 560 | ], 561 | "stateMutability": "view", 562 | "type": "function" 563 | }, 564 | { 565 | "inputs": [], 566 | "name": "owner", 567 | "outputs": [ 568 | { 569 | "internalType": "address", 570 | "name": "", 571 | "type": "address" 572 | } 573 | ], 574 | "stateMutability": "view", 575 | "type": "function" 576 | }, 577 | { 578 | "inputs": [ 579 | { 580 | "internalType": "uint256", 581 | "name": "tokenId", 582 | "type": "uint256" 583 | } 584 | ], 585 | "name": "ownerOf", 586 | "outputs": [ 587 | { 588 | "internalType": "address", 589 | "name": "", 590 | "type": "address" 591 | } 592 | ], 593 | "stateMutability": "view", 594 | "type": "function" 595 | }, 596 | { 597 | "inputs": [], 598 | "name": "paused", 599 | "outputs": [ 600 | { 601 | "internalType": "bool", 602 | "name": "", 603 | "type": "bool" 604 | } 605 | ], 606 | "stateMutability": "view", 607 | "type": "function" 608 | }, 609 | { 610 | "inputs": [ 611 | { 612 | "internalType": "bytes4", 613 | "name": "interfaceId", 614 | "type": "bytes4" 615 | } 616 | ], 617 | "name": "supportsInterface", 618 | "outputs": [ 619 | { 620 | "internalType": "bool", 621 | "name": "", 622 | "type": "bool" 623 | } 624 | ], 625 | "stateMutability": "view", 626 | "type": "function" 627 | }, 628 | { 629 | "inputs": [], 630 | "name": "symbol", 631 | "outputs": [ 632 | { 633 | "internalType": "string", 634 | "name": "", 635 | "type": "string" 636 | } 637 | ], 638 | "stateMutability": "view", 639 | "type": "function" 640 | }, 641 | { 642 | "inputs": [ 643 | { 644 | "internalType": "uint256", 645 | "name": "index", 646 | "type": "uint256" 647 | } 648 | ], 649 | "name": "tokenByIndex", 650 | "outputs": [ 651 | { 652 | "internalType": "uint256", 653 | "name": "", 654 | "type": "uint256" 655 | } 656 | ], 657 | "stateMutability": "view", 658 | "type": "function" 659 | }, 660 | { 661 | "inputs": [ 662 | { 663 | "internalType": "address", 664 | "name": "owner", 665 | "type": "address" 666 | }, 667 | { 668 | "internalType": "uint256", 669 | "name": "index", 670 | "type": "uint256" 671 | } 672 | ], 673 | "name": "tokenOfOwnerByIndex", 674 | "outputs": [ 675 | { 676 | "internalType": "uint256", 677 | "name": "", 678 | "type": "uint256" 679 | } 680 | ], 681 | "stateMutability": "view", 682 | "type": "function" 683 | }, 684 | { 685 | "inputs": [ 686 | { 687 | "internalType": "uint256", 688 | "name": "tokenId", 689 | "type": "uint256" 690 | } 691 | ], 692 | "name": "tokenURI", 693 | "outputs": [ 694 | { 695 | "internalType": "string", 696 | "name": "", 697 | "type": "string" 698 | } 699 | ], 700 | "stateMutability": "view", 701 | "type": "function" 702 | }, 703 | { 704 | "inputs": [], 705 | "name": "totalSupply", 706 | "outputs": [ 707 | { 708 | "internalType": "uint256", 709 | "name": "", 710 | "type": "uint256" 711 | } 712 | ], 713 | "stateMutability": "view", 714 | "type": "function" 715 | }, 716 | { 717 | "inputs": [ 718 | { 719 | "internalType": "address", 720 | "name": "_owner", 721 | "type": "address" 722 | } 723 | ], 724 | "name": "walletOfOwner", 725 | "outputs": [ 726 | { 727 | "internalType": "uint256[]", 728 | "name": "", 729 | "type": "uint256[]" 730 | } 731 | ], 732 | "stateMutability": "view", 733 | "type": "function" 734 | } 735 | ] -------------------------------------------------------------------------------- /Part3-NextJS-Market-WebFrontEnd/engine/Resell.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "uint256", 8 | "name": "itemId", 9 | "type": "uint256" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "uint256", 14 | "name": "tokenId", 15 | "type": "uint256" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "address", 20 | "name": "seller", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "owner", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "uint256", 32 | "name": "price", 33 | "type": "uint256" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "bool", 38 | "name": "sold", 39 | "type": "bool" 40 | } 41 | ], 42 | "name": "NFTListCreated", 43 | "type": "event" 44 | }, 45 | { 46 | "inputs": [ 47 | { 48 | "internalType": "uint256", 49 | "name": "itemId", 50 | "type": "uint256" 51 | } 52 | ], 53 | "name": "buyNft", 54 | "outputs": [], 55 | "stateMutability": "payable", 56 | "type": "function" 57 | }, 58 | { 59 | "inputs": [ 60 | { 61 | "internalType": "uint256", 62 | "name": "tokenId", 63 | "type": "uint256" 64 | }, 65 | { 66 | "internalType": "uint256", 67 | "name": "price", 68 | "type": "uint256" 69 | } 70 | ], 71 | "name": "listSale", 72 | "outputs": [], 73 | "stateMutability": "payable", 74 | "type": "function" 75 | }, 76 | { 77 | "inputs": [ 78 | { 79 | "internalType": "contract ERC721Enumerable", 80 | "name": "_nft", 81 | "type": "address" 82 | } 83 | ], 84 | "stateMutability": "nonpayable", 85 | "type": "constructor" 86 | }, 87 | { 88 | "inputs": [], 89 | "name": "getListingFee", 90 | "outputs": [ 91 | { 92 | "internalType": "uint256", 93 | "name": "", 94 | "type": "uint256" 95 | } 96 | ], 97 | "stateMutability": "view", 98 | "type": "function" 99 | }, 100 | { 101 | "inputs": [], 102 | "name": "nftListings", 103 | "outputs": [ 104 | { 105 | "components": [ 106 | { 107 | "internalType": "uint256", 108 | "name": "itemId", 109 | "type": "uint256" 110 | }, 111 | { 112 | "internalType": "uint256", 113 | "name": "tokenId", 114 | "type": "uint256" 115 | }, 116 | { 117 | "internalType": "address payable", 118 | "name": "seller", 119 | "type": "address" 120 | }, 121 | { 122 | "internalType": "address payable", 123 | "name": "owner", 124 | "type": "address" 125 | }, 126 | { 127 | "internalType": "uint256", 128 | "name": "price", 129 | "type": "uint256" 130 | }, 131 | { 132 | "internalType": "bool", 133 | "name": "sold", 134 | "type": "bool" 135 | } 136 | ], 137 | "internalType": "struct NFTMarketResell.List[]", 138 | "name": "", 139 | "type": "tuple[]" 140 | } 141 | ], 142 | "stateMutability": "view", 143 | "type": "function" 144 | }, 145 | { 146 | "inputs": [ 147 | { 148 | "internalType": "address", 149 | "name": "", 150 | "type": "address" 151 | }, 152 | { 153 | "internalType": "address", 154 | "name": "from", 155 | "type": "address" 156 | }, 157 | { 158 | "internalType": "uint256", 159 | "name": "", 160 | "type": "uint256" 161 | }, 162 | { 163 | "internalType": "bytes", 164 | "name": "", 165 | "type": "bytes" 166 | } 167 | ], 168 | "name": "onERC721Received", 169 | "outputs": [ 170 | { 171 | "internalType": "bytes4", 172 | "name": "", 173 | "type": "bytes4" 174 | } 175 | ], 176 | "stateMutability": "pure", 177 | "type": "function" 178 | }, 179 | { 180 | "inputs": [ 181 | { 182 | "internalType": "uint256", 183 | "name": "", 184 | "type": "uint256" 185 | } 186 | ], 187 | "name": "vaultItems", 188 | "outputs": [ 189 | { 190 | "internalType": "uint256", 191 | "name": "itemId", 192 | "type": "uint256" 193 | }, 194 | { 195 | "internalType": "uint256", 196 | "name": "tokenId", 197 | "type": "uint256" 198 | }, 199 | { 200 | "internalType": "address payable", 201 | "name": "seller", 202 | "type": "address" 203 | }, 204 | { 205 | "internalType": "address payable", 206 | "name": "owner", 207 | "type": "address" 208 | }, 209 | { 210 | "internalType": "uint256", 211 | "name": "price", 212 | "type": "uint256" 213 | }, 214 | { 215 | "internalType": "bool", 216 | "name": "sold", 217 | "type": "bool" 218 | } 219 | ], 220 | "stateMutability": "view", 221 | "type": "function" 222 | } 223 | ] -------------------------------------------------------------------------------- /Part3-NextJS-Market-WebFrontEnd/engine/configuration.js: -------------------------------------------------------------------------------- 1 | /* 2 | ___ ___ _ _ ___ _____ __ __ _ _ 3 | _ _ |_ )| \ | \| || __||_ _| | \/ | __ _ _ _ | |__ ___ | |_ 4 | | ' \ / / | |) | | .` || _| | | | |\/| |/ _` || '_|| / // -_)| _| 5 | |_||_|/___||___/ |_|\_||_| |_| |_| |_|\__,_||_| |_\_\\___| \__| 6 | 7 | Update values accordingly 8 | xxnft is the NFT SmartContract Address 9 | xxmarket is the NFT MarketPlace Address 10 | xxresell is the NFT MarketResell Address 11 | xxnftcol is the already create NFT Collection Address 12 | */ 13 | 14 | /* 15 | Private Key Encryption 16 | Replace ethraw with your private key "0xPRIVATEKEY" (Ethereum and other EVM) 17 | Replace hhraw with your private key "0xPRIVATEKEY" (Hardhat) 18 | */ 19 | 20 | import SimpleCrypto from "simple-crypto-js" 21 | const cipherKey = "#ffg3$dvcv4rtkljjkh38dfkhhjgt" 22 | const ethraw = "0x8207b7bbf486039b455923a402560ed041ad4b7243e9f329d6e415c00aaa9ef2"; 23 | const hhraw = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; 24 | export const simpleCrypto = new SimpleCrypto(cipherKey) 25 | export const cipherEth = simpleCrypto.encrypt(ethraw) 26 | export const cipherHH = simpleCrypto.encrypt(hhraw) 27 | 28 | /* 29 | HardHat Testnet 30 | */ 31 | 32 | export var hhresell = "0xCd55135cC103D7568056a828100D96603380DDbE"; 33 | export var hhnftcol = "0x45A755B058492558351f188e4362F0546Bc3d140"; 34 | var hhrpc = "http://localhost:8545"; 35 | 36 | /* 37 | Global Parameters 38 | */ 39 | export var mainnet = hhrpc -------------------------------------------------------------------------------- /Part3-NextJS-Market-WebFrontEnd/index.js: -------------------------------------------------------------------------------- 1 | import Head from 'next/head' 2 | import Image from 'next/image' 3 | import styles from '../styles/Home.module.css' 4 | 5 | export default function Home() { 6 | return ( 7 |
8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /Part3-NextJS-Market-WebFrontEnd/portal.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useState, useEffect } from 'react'; 3 | import Web3Modal from "web3modal"; 4 | import { useRouter } from 'next/router'; 5 | import Resell from '../engine/Resell.json'; 6 | import NFTCollection from '../engine/NFTCollection.json'; 7 | import { Card, Button, Input, Col, Row, Spacer, Container, Text, Grid } from '@nextui-org/react'; 8 | import axios from 'axios'; 9 | import 'sf-font'; 10 | import Web3 from 'web3'; 11 | import { hhresell, hhnftcol, mainnet, cipherHH, simpleCrypto } from '../engine/configuration'; 12 | 13 | 14 | export default function Sell() { 15 | const [user, getUser] = useState([]) 16 | const [resalePrice, updateresalePrice] = useState({ price: ''}) 17 | const [nfts, setNfts] = useState([]) 18 | const [loadingState, setLoadingState] = useState('not-loaded') 19 | useEffect(() => { 20 | connectUser(); 21 | getWalletNFTs() 22 | }, [setNfts,getUser]) 23 | const router = useRouter() 24 | 25 | async function connectUser() { 26 | if (window.ethereum) { 27 | var web3 = new Web3(window.ethereum); 28 | await window.ethereum.send('eth_requestAccounts'); 29 | var accounts = await web3.eth.getAccounts(); 30 | var account = accounts[0]; 31 | } 32 | getUser(account) 33 | } 34 | 35 | async function getWalletNFTs() { 36 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 37 | const key = simpleCrypto.decrypt(cipherHH) 38 | const wallet = new ethers.Wallet(key, provider); 39 | const contract = new ethers.Contract(hhnftcol, NFTCollection, wallet); 40 | const itemArray = []; 41 | contract.totalSupply().then(result => { 42 | let totalSup = parseInt(result, 16) 43 | for (let i = 0; i < totalSup; i++) { 44 | var token = i + 1 45 | const owner = contract.ownerOf(token).catch(function (error) { 46 | console.log("tokens filtered"); 47 | }); 48 | const rawUri = contract.tokenURI(token).catch(function (error) { 49 | console.log("tokens filtered"); 50 | }); 51 | const Uri = Promise.resolve(rawUri) 52 | const getUri = Uri.then(value => { 53 | let str = value 54 | let cleanUri = str.replace('ipfs://', 'https://ipfs.io/ipfs/') 55 | console.log(cleanUri) 56 | let metadata = axios.get(cleanUri).catch(function (error) { 57 | console.log(error.toJSON()); 58 | }); 59 | return metadata; 60 | }) 61 | getUri.then(value => { 62 | let rawImg = value.data.image 63 | var name = value.data.name 64 | var desc = value.data.description 65 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 66 | Promise.resolve(owner).then(value => { 67 | let ownerW = value; 68 | let meta = { 69 | name: name, 70 | img: image, 71 | tokenId: token, 72 | wallet: ownerW, 73 | desc, 74 | } 75 | console.log(meta) 76 | itemArray.push(meta) 77 | }) 78 | }) 79 | } 80 | }) 81 | await new Promise(r => setTimeout(r, 3000)); 82 | setNfts(itemArray) 83 | setLoadingState('loaded'); 84 | } 85 | 86 | if (loadingState === 'loaded' && !nfts.length) 87 | return ( 88 | 89 | 90 | 91 | No NFT's Found, Connect Wallet 92 | 93 | 94 | 95 | 96 | ) 97 | return ( 98 |
99 | 100 | 101 | 102 | NFT's in Wallet {user} 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | {nfts.map((nft, i) => { 111 | var owner = user 112 | if (owner.indexOf(nft.wallet) !== -1) { 113 | async function executeRelist() { 114 | const { price } = resalePrice 115 | if (!price) return 116 | try { 117 | relistNFT() 118 | } catch (error) { 119 | console.log('Transaction Failed', error) 120 | } 121 | } 122 | async function relistNFT() { 123 | const web3Modal = new Web3Modal() 124 | const connection = await web3Modal.connect() 125 | const provider = new ethers.providers.Web3Provider(connection) 126 | const signer = provider.getSigner() 127 | const price = ethers.utils.parseUnits(resalePrice.price, 'ether') 128 | const contractnft = new ethers.Contract(hhnftcol, NFTCollection, signer); 129 | await contractnft.setApprovalForAll(hhresell, true); 130 | let contract = new ethers.Contract(hhresell, Resell, signer) 131 | let listingFee = await contract.getListingFee() 132 | listingFee = listingFee.toString() 133 | let transaction = await contract.listSale(nft.tokenId, price, { value: listingFee }) 134 | await transaction.wait() 135 | router.push('/') 136 | } 137 | return ( 138 | 139 | 140 | 141 | 142 | 143 |

Owned by You

144 | {nft.name} Token-{nft.tokenId} 145 | {nft.desc} 146 | updateresalePrice({ ...resalePrice, price: e.target.value })} 151 | /> 152 | 153 |
154 |
155 |
156 |
157 | ) 158 | }})} 159 |
160 |
161 |
162 | ) 163 | } -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/_app.js: -------------------------------------------------------------------------------- 1 | import { createTheme, NextUIProvider } from "@nextui-org/react"; 2 | import 'sf-font'; 3 | import Link from 'next/link' 4 | import { Spacer, Button, Col, Row, Container, Dropdown, Text } from '@nextui-org/react'; 5 | import react from "react"; 6 | import Footer from './footer'; 7 | 8 | const theme = createTheme({ 9 | type: "dark", 10 | theme: { 11 | fontFamily:'SF Pro Display', 12 | colors: { 13 | primaryLight: '$blue200', 14 | primaryLightHover: '$blue300', 15 | primaryLightActive: '$blue400', 16 | primaryLightContrast: '$blue600', 17 | primary: '$purple500', 18 | primaryBorder: '$blue500', 19 | primaryBorderHover: '$blue600', 20 | primarySolidHover: '$blue700', 21 | primarySolidContrast: '$white', 22 | primaryShadow: '$white500', 23 | transparent: '#00000000', 24 | 25 | gradient: 'linear-gradient(112deg, $blue100 -25%, $pink500 -10%, $purple300 90%)', 26 | link: '#5E1DAD', 27 | 28 | myColor: '#00000030' 29 | 30 | }, 31 | space: {}, 32 | fonts: {} 33 | } 34 | }) 35 | 36 | function MyApp({ Component, pageProps }) { 37 | 38 | return( 39 |
40 |
41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 58 | 59 | 60 | 61 | 62 | 72 | 73 | 74 | 75 | 88 | 89 | 90 | 91 | 92 | 93 | 94 |
98 |
99 | 100 | ) 101 | 102 | 103 | } 104 | 105 | export default MyApp 106 | -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/engine/NFTCollection.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "owner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "approved", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "Approval", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "owner", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "operator", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "bool", 45 | "name": "approved", 46 | "type": "bool" 47 | } 48 | ], 49 | "name": "ApprovalForAll", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "previousOwner", 59 | "type": "address" 60 | }, 61 | { 62 | "indexed": true, 63 | "internalType": "address", 64 | "name": "newOwner", 65 | "type": "address" 66 | } 67 | ], 68 | "name": "OwnershipTransferred", 69 | "type": "event" 70 | }, 71 | { 72 | "anonymous": false, 73 | "inputs": [ 74 | { 75 | "indexed": true, 76 | "internalType": "address", 77 | "name": "from", 78 | "type": "address" 79 | }, 80 | { 81 | "indexed": true, 82 | "internalType": "address", 83 | "name": "to", 84 | "type": "address" 85 | }, 86 | { 87 | "indexed": true, 88 | "internalType": "uint256", 89 | "name": "tokenId", 90 | "type": "uint256" 91 | } 92 | ], 93 | "name": "Transfer", 94 | "type": "event" 95 | }, 96 | { 97 | "inputs": [ 98 | { 99 | "internalType": "contract IERC20", 100 | "name": "_paytoken", 101 | "type": "address" 102 | }, 103 | { 104 | "internalType": "uint256", 105 | "name": "_costvalue", 106 | "type": "uint256" 107 | } 108 | ], 109 | "name": "addCurrency", 110 | "outputs": [], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "address", 118 | "name": "to", 119 | "type": "address" 120 | }, 121 | { 122 | "internalType": "uint256", 123 | "name": "tokenId", 124 | "type": "uint256" 125 | } 126 | ], 127 | "name": "approve", 128 | "outputs": [], 129 | "stateMutability": "nonpayable", 130 | "type": "function" 131 | }, 132 | { 133 | "inputs": [ 134 | { 135 | "internalType": "address", 136 | "name": "_to", 137 | "type": "address" 138 | }, 139 | { 140 | "internalType": "uint256", 141 | "name": "_mintAmount", 142 | "type": "uint256" 143 | } 144 | ], 145 | "name": "mint", 146 | "outputs": [], 147 | "stateMutability": "payable", 148 | "type": "function" 149 | }, 150 | { 151 | "inputs": [ 152 | { 153 | "internalType": "address", 154 | "name": "_to", 155 | "type": "address" 156 | }, 157 | { 158 | "internalType": "uint256", 159 | "name": "_mintAmount", 160 | "type": "uint256" 161 | }, 162 | { 163 | "internalType": "uint256", 164 | "name": "_pid", 165 | "type": "uint256" 166 | } 167 | ], 168 | "name": "mintpid", 169 | "outputs": [], 170 | "stateMutability": "payable", 171 | "type": "function" 172 | }, 173 | { 174 | "inputs": [ 175 | { 176 | "internalType": "bool", 177 | "name": "_state", 178 | "type": "bool" 179 | } 180 | ], 181 | "name": "pause", 182 | "outputs": [], 183 | "stateMutability": "nonpayable", 184 | "type": "function" 185 | }, 186 | { 187 | "inputs": [], 188 | "name": "renounceOwnership", 189 | "outputs": [], 190 | "stateMutability": "nonpayable", 191 | "type": "function" 192 | }, 193 | { 194 | "inputs": [ 195 | { 196 | "internalType": "address", 197 | "name": "from", 198 | "type": "address" 199 | }, 200 | { 201 | "internalType": "address", 202 | "name": "to", 203 | "type": "address" 204 | }, 205 | { 206 | "internalType": "uint256", 207 | "name": "tokenId", 208 | "type": "uint256" 209 | } 210 | ], 211 | "name": "safeTransferFrom", 212 | "outputs": [], 213 | "stateMutability": "nonpayable", 214 | "type": "function" 215 | }, 216 | { 217 | "inputs": [ 218 | { 219 | "internalType": "address", 220 | "name": "from", 221 | "type": "address" 222 | }, 223 | { 224 | "internalType": "address", 225 | "name": "to", 226 | "type": "address" 227 | }, 228 | { 229 | "internalType": "uint256", 230 | "name": "tokenId", 231 | "type": "uint256" 232 | }, 233 | { 234 | "internalType": "bytes", 235 | "name": "_data", 236 | "type": "bytes" 237 | } 238 | ], 239 | "name": "safeTransferFrom", 240 | "outputs": [], 241 | "stateMutability": "nonpayable", 242 | "type": "function" 243 | }, 244 | { 245 | "inputs": [ 246 | { 247 | "internalType": "address", 248 | "name": "operator", 249 | "type": "address" 250 | }, 251 | { 252 | "internalType": "bool", 253 | "name": "approved", 254 | "type": "bool" 255 | } 256 | ], 257 | "name": "setApprovalForAll", 258 | "outputs": [], 259 | "stateMutability": "nonpayable", 260 | "type": "function" 261 | }, 262 | { 263 | "inputs": [ 264 | { 265 | "internalType": "string", 266 | "name": "_newBaseExtension", 267 | "type": "string" 268 | } 269 | ], 270 | "name": "setBaseExtension", 271 | "outputs": [], 272 | "stateMutability": "nonpayable", 273 | "type": "function" 274 | }, 275 | { 276 | "inputs": [ 277 | { 278 | "internalType": "string", 279 | "name": "_newBaseURI", 280 | "type": "string" 281 | } 282 | ], 283 | "name": "setBaseURI", 284 | "outputs": [], 285 | "stateMutability": "nonpayable", 286 | "type": "function" 287 | }, 288 | { 289 | "inputs": [ 290 | { 291 | "internalType": "uint256", 292 | "name": "_newmaxMintAmount", 293 | "type": "uint256" 294 | } 295 | ], 296 | "name": "setmaxMintAmount", 297 | "outputs": [], 298 | "stateMutability": "nonpayable", 299 | "type": "function" 300 | }, 301 | { 302 | "inputs": [ 303 | { 304 | "internalType": "address", 305 | "name": "from", 306 | "type": "address" 307 | }, 308 | { 309 | "internalType": "address", 310 | "name": "to", 311 | "type": "address" 312 | }, 313 | { 314 | "internalType": "uint256", 315 | "name": "tokenId", 316 | "type": "uint256" 317 | } 318 | ], 319 | "name": "transferFrom", 320 | "outputs": [], 321 | "stateMutability": "nonpayable", 322 | "type": "function" 323 | }, 324 | { 325 | "inputs": [ 326 | { 327 | "internalType": "address", 328 | "name": "newOwner", 329 | "type": "address" 330 | } 331 | ], 332 | "name": "transferOwnership", 333 | "outputs": [], 334 | "stateMutability": "nonpayable", 335 | "type": "function" 336 | }, 337 | { 338 | "inputs": [], 339 | "name": "withdraw", 340 | "outputs": [], 341 | "stateMutability": "payable", 342 | "type": "function" 343 | }, 344 | { 345 | "inputs": [ 346 | { 347 | "internalType": "uint256", 348 | "name": "_pid", 349 | "type": "uint256" 350 | } 351 | ], 352 | "name": "withdrawcustom", 353 | "outputs": [], 354 | "stateMutability": "payable", 355 | "type": "function" 356 | }, 357 | { 358 | "inputs": [], 359 | "stateMutability": "nonpayable", 360 | "type": "constructor" 361 | }, 362 | { 363 | "inputs": [ 364 | { 365 | "internalType": "uint256", 366 | "name": "", 367 | "type": "uint256" 368 | } 369 | ], 370 | "name": "AllowedCrypto", 371 | "outputs": [ 372 | { 373 | "internalType": "contract IERC20", 374 | "name": "paytoken", 375 | "type": "address" 376 | }, 377 | { 378 | "internalType": "uint256", 379 | "name": "costvalue", 380 | "type": "uint256" 381 | } 382 | ], 383 | "stateMutability": "view", 384 | "type": "function" 385 | }, 386 | { 387 | "inputs": [ 388 | { 389 | "internalType": "address", 390 | "name": "owner", 391 | "type": "address" 392 | } 393 | ], 394 | "name": "balanceOf", 395 | "outputs": [ 396 | { 397 | "internalType": "uint256", 398 | "name": "", 399 | "type": "uint256" 400 | } 401 | ], 402 | "stateMutability": "view", 403 | "type": "function" 404 | }, 405 | { 406 | "inputs": [], 407 | "name": "baseExtension", 408 | "outputs": [ 409 | { 410 | "internalType": "string", 411 | "name": "", 412 | "type": "string" 413 | } 414 | ], 415 | "stateMutability": "view", 416 | "type": "function" 417 | }, 418 | { 419 | "inputs": [], 420 | "name": "baseURI", 421 | "outputs": [ 422 | { 423 | "internalType": "string", 424 | "name": "", 425 | "type": "string" 426 | } 427 | ], 428 | "stateMutability": "view", 429 | "type": "function" 430 | }, 431 | { 432 | "inputs": [], 433 | "name": "cost", 434 | "outputs": [ 435 | { 436 | "internalType": "uint256", 437 | "name": "", 438 | "type": "uint256" 439 | } 440 | ], 441 | "stateMutability": "view", 442 | "type": "function" 443 | }, 444 | { 445 | "inputs": [ 446 | { 447 | "internalType": "uint256", 448 | "name": "tokenId", 449 | "type": "uint256" 450 | } 451 | ], 452 | "name": "getApproved", 453 | "outputs": [ 454 | { 455 | "internalType": "address", 456 | "name": "", 457 | "type": "address" 458 | } 459 | ], 460 | "stateMutability": "view", 461 | "type": "function" 462 | }, 463 | { 464 | "inputs": [ 465 | { 466 | "internalType": "uint256", 467 | "name": "_pid", 468 | "type": "uint256" 469 | } 470 | ], 471 | "name": "getCryptotoken", 472 | "outputs": [ 473 | { 474 | "internalType": "contract IERC20", 475 | "name": "", 476 | "type": "address" 477 | } 478 | ], 479 | "stateMutability": "view", 480 | "type": "function" 481 | }, 482 | { 483 | "inputs": [ 484 | { 485 | "internalType": "uint256", 486 | "name": "_pid", 487 | "type": "uint256" 488 | } 489 | ], 490 | "name": "getNFTCost", 491 | "outputs": [ 492 | { 493 | "internalType": "uint256", 494 | "name": "", 495 | "type": "uint256" 496 | } 497 | ], 498 | "stateMutability": "view", 499 | "type": "function" 500 | }, 501 | { 502 | "inputs": [ 503 | { 504 | "internalType": "address", 505 | "name": "owner", 506 | "type": "address" 507 | }, 508 | { 509 | "internalType": "address", 510 | "name": "operator", 511 | "type": "address" 512 | } 513 | ], 514 | "name": "isApprovedForAll", 515 | "outputs": [ 516 | { 517 | "internalType": "bool", 518 | "name": "", 519 | "type": "bool" 520 | } 521 | ], 522 | "stateMutability": "view", 523 | "type": "function" 524 | }, 525 | { 526 | "inputs": [], 527 | "name": "maxMintAmount", 528 | "outputs": [ 529 | { 530 | "internalType": "uint256", 531 | "name": "", 532 | "type": "uint256" 533 | } 534 | ], 535 | "stateMutability": "view", 536 | "type": "function" 537 | }, 538 | { 539 | "inputs": [], 540 | "name": "maxSupply", 541 | "outputs": [ 542 | { 543 | "internalType": "uint256", 544 | "name": "", 545 | "type": "uint256" 546 | } 547 | ], 548 | "stateMutability": "view", 549 | "type": "function" 550 | }, 551 | { 552 | "inputs": [], 553 | "name": "name", 554 | "outputs": [ 555 | { 556 | "internalType": "string", 557 | "name": "", 558 | "type": "string" 559 | } 560 | ], 561 | "stateMutability": "view", 562 | "type": "function" 563 | }, 564 | { 565 | "inputs": [], 566 | "name": "owner", 567 | "outputs": [ 568 | { 569 | "internalType": "address", 570 | "name": "", 571 | "type": "address" 572 | } 573 | ], 574 | "stateMutability": "view", 575 | "type": "function" 576 | }, 577 | { 578 | "inputs": [ 579 | { 580 | "internalType": "uint256", 581 | "name": "tokenId", 582 | "type": "uint256" 583 | } 584 | ], 585 | "name": "ownerOf", 586 | "outputs": [ 587 | { 588 | "internalType": "address", 589 | "name": "", 590 | "type": "address" 591 | } 592 | ], 593 | "stateMutability": "view", 594 | "type": "function" 595 | }, 596 | { 597 | "inputs": [], 598 | "name": "paused", 599 | "outputs": [ 600 | { 601 | "internalType": "bool", 602 | "name": "", 603 | "type": "bool" 604 | } 605 | ], 606 | "stateMutability": "view", 607 | "type": "function" 608 | }, 609 | { 610 | "inputs": [ 611 | { 612 | "internalType": "bytes4", 613 | "name": "interfaceId", 614 | "type": "bytes4" 615 | } 616 | ], 617 | "name": "supportsInterface", 618 | "outputs": [ 619 | { 620 | "internalType": "bool", 621 | "name": "", 622 | "type": "bool" 623 | } 624 | ], 625 | "stateMutability": "view", 626 | "type": "function" 627 | }, 628 | { 629 | "inputs": [], 630 | "name": "symbol", 631 | "outputs": [ 632 | { 633 | "internalType": "string", 634 | "name": "", 635 | "type": "string" 636 | } 637 | ], 638 | "stateMutability": "view", 639 | "type": "function" 640 | }, 641 | { 642 | "inputs": [ 643 | { 644 | "internalType": "uint256", 645 | "name": "index", 646 | "type": "uint256" 647 | } 648 | ], 649 | "name": "tokenByIndex", 650 | "outputs": [ 651 | { 652 | "internalType": "uint256", 653 | "name": "", 654 | "type": "uint256" 655 | } 656 | ], 657 | "stateMutability": "view", 658 | "type": "function" 659 | }, 660 | { 661 | "inputs": [ 662 | { 663 | "internalType": "address", 664 | "name": "owner", 665 | "type": "address" 666 | }, 667 | { 668 | "internalType": "uint256", 669 | "name": "index", 670 | "type": "uint256" 671 | } 672 | ], 673 | "name": "tokenOfOwnerByIndex", 674 | "outputs": [ 675 | { 676 | "internalType": "uint256", 677 | "name": "", 678 | "type": "uint256" 679 | } 680 | ], 681 | "stateMutability": "view", 682 | "type": "function" 683 | }, 684 | { 685 | "inputs": [ 686 | { 687 | "internalType": "uint256", 688 | "name": "tokenId", 689 | "type": "uint256" 690 | } 691 | ], 692 | "name": "tokenURI", 693 | "outputs": [ 694 | { 695 | "internalType": "string", 696 | "name": "", 697 | "type": "string" 698 | } 699 | ], 700 | "stateMutability": "view", 701 | "type": "function" 702 | }, 703 | { 704 | "inputs": [], 705 | "name": "totalSupply", 706 | "outputs": [ 707 | { 708 | "internalType": "uint256", 709 | "name": "", 710 | "type": "uint256" 711 | } 712 | ], 713 | "stateMutability": "view", 714 | "type": "function" 715 | }, 716 | { 717 | "inputs": [ 718 | { 719 | "internalType": "address", 720 | "name": "_owner", 721 | "type": "address" 722 | } 723 | ], 724 | "name": "walletOfOwner", 725 | "outputs": [ 726 | { 727 | "internalType": "uint256[]", 728 | "name": "", 729 | "type": "uint256[]" 730 | } 731 | ], 732 | "stateMutability": "view", 733 | "type": "function" 734 | } 735 | ] -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/engine/Resell.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "uint256", 8 | "name": "tokenId", 9 | "type": "uint256" 10 | }, 11 | { 12 | "indexed": false, 13 | "internalType": "address", 14 | "name": "seller", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": false, 19 | "internalType": "address", 20 | "name": "owner", 21 | "type": "address" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "uint256", 26 | "name": "price", 27 | "type": "uint256" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "bool", 32 | "name": "sold", 33 | "type": "bool" 34 | } 35 | ], 36 | "name": "NFTListCreated", 37 | "type": "event" 38 | }, 39 | { 40 | "inputs": [ 41 | { 42 | "internalType": "uint256", 43 | "name": "tokenId", 44 | "type": "uint256" 45 | } 46 | ], 47 | "name": "buyNft", 48 | "outputs": [], 49 | "stateMutability": "payable", 50 | "type": "function" 51 | }, 52 | { 53 | "inputs": [ 54 | { 55 | "internalType": "uint256", 56 | "name": "tokenId", 57 | "type": "uint256" 58 | } 59 | ], 60 | "name": "cancelSale", 61 | "outputs": [], 62 | "stateMutability": "nonpayable", 63 | "type": "function" 64 | }, 65 | { 66 | "inputs": [ 67 | { 68 | "internalType": "uint256", 69 | "name": "tokenId", 70 | "type": "uint256" 71 | }, 72 | { 73 | "internalType": "uint256", 74 | "name": "price", 75 | "type": "uint256" 76 | } 77 | ], 78 | "name": "listSale", 79 | "outputs": [], 80 | "stateMutability": "payable", 81 | "type": "function" 82 | }, 83 | { 84 | "inputs": [ 85 | { 86 | "internalType": "contract ERC721Enumerable", 87 | "name": "_nft", 88 | "type": "address" 89 | } 90 | ], 91 | "stateMutability": "nonpayable", 92 | "type": "constructor" 93 | }, 94 | { 95 | "inputs": [], 96 | "name": "getListingFee", 97 | "outputs": [ 98 | { 99 | "internalType": "uint256", 100 | "name": "", 101 | "type": "uint256" 102 | } 103 | ], 104 | "stateMutability": "view", 105 | "type": "function" 106 | }, 107 | { 108 | "inputs": [ 109 | { 110 | "internalType": "uint256", 111 | "name": "tokenId", 112 | "type": "uint256" 113 | } 114 | ], 115 | "name": "getPrice", 116 | "outputs": [ 117 | { 118 | "internalType": "uint256", 119 | "name": "", 120 | "type": "uint256" 121 | } 122 | ], 123 | "stateMutability": "view", 124 | "type": "function" 125 | }, 126 | { 127 | "inputs": [ 128 | { 129 | "internalType": "address", 130 | "name": "", 131 | "type": "address" 132 | }, 133 | { 134 | "internalType": "address", 135 | "name": "from", 136 | "type": "address" 137 | }, 138 | { 139 | "internalType": "uint256", 140 | "name": "", 141 | "type": "uint256" 142 | }, 143 | { 144 | "internalType": "bytes", 145 | "name": "", 146 | "type": "bytes" 147 | } 148 | ], 149 | "name": "onERC721Received", 150 | "outputs": [ 151 | { 152 | "internalType": "bytes4", 153 | "name": "", 154 | "type": "bytes4" 155 | } 156 | ], 157 | "stateMutability": "pure", 158 | "type": "function" 159 | }, 160 | { 161 | "inputs": [ 162 | { 163 | "internalType": "uint256", 164 | "name": "", 165 | "type": "uint256" 166 | } 167 | ], 168 | "name": "vaultItems", 169 | "outputs": [ 170 | { 171 | "internalType": "uint256", 172 | "name": "tokenId", 173 | "type": "uint256" 174 | }, 175 | { 176 | "internalType": "address payable", 177 | "name": "seller", 178 | "type": "address" 179 | }, 180 | { 181 | "internalType": "address payable", 182 | "name": "owner", 183 | "type": "address" 184 | }, 185 | { 186 | "internalType": "uint256", 187 | "name": "price", 188 | "type": "uint256" 189 | }, 190 | { 191 | "internalType": "bool", 192 | "name": "sold", 193 | "type": "bool" 194 | } 195 | ], 196 | "stateMutability": "view", 197 | "type": "function" 198 | } 199 | ] -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/engine/configuration.js: -------------------------------------------------------------------------------- 1 | /* 2 | ___ ___ _ _ ___ _____ __ __ _ _ 3 | _ _ |_ )| \ | \| || __||_ _| | \/ | __ _ _ _ | |__ ___ | |_ 4 | | ' \ / / | |) | | .` || _| | | | |\/| |/ _` || '_|| / // -_)| _| 5 | |_||_|/___||___/ |_|\_||_| |_| |_| |_|\__,_||_| |_\_\\___| \__| 6 | 7 | Update values accordingly 8 | */ 9 | 10 | /* 11 | Private Key Encryption 12 | Replace hhraw with your contract 13 | owner wallet private key "0xPRIVATEKEY" 14 | */ 15 | 16 | import SimpleCrypto from "simple-crypto-js" 17 | const cipherKey = "#ffg3$dvcv4rtkljjkh38dfkhhjgt" 18 | const hhraw = "0xREPLACEWITHPRIVATEKEY"; 19 | export const simpleCrypto = new SimpleCrypto(cipherKey) 20 | export const cipherEth = simpleCrypto.encrypt(hhraw) 21 | export const cipherHH = simpleCrypto.encrypt(hhraw) 22 | 23 | /* 24 | MARKET AND NFT CONTRACTS 25 | */ 26 | export var hhresell = "REPLACE WITH YOUR RESELL SMART CONTRACT"; 27 | export var hhnftcol = "REPLACE WITH YOUR NFT COLLECTION CONTRACT"; 28 | 29 | /* 30 | NETWORK RPC ADDRESSES, Choose one then 31 | change the value of "hhrpc" below. 32 | */ 33 | var mumbai = 'https://matic-mumbai.chainstacklabs.com'; 34 | var goerli = 'https://rpc.ankr.com/eth_goerli'; 35 | var rinkeby = 'https://rpc.ankr.com/eth_rinkeby'; 36 | 37 | /* 38 | CHANGE THIS TO YOUR PREFERRED TESTNET 39 | */ 40 | var hhrpc = goerli; 41 | /* 42 | Global Parameters 43 | */ 44 | export var mainnet = hhrpc 45 | 46 | /* 47 | DON'T FORGET TO SAVE! 48 | */ -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/footer.js: -------------------------------------------------------------------------------- 1 | import 'sf-font'; 2 | import { Text, Row, Spacer, Container, Col } from '@nextui-org/react'; 3 | 4 | export default function Footer() { 5 | 6 | const footer1 = [ 7 | { 8 | id: 1, 9 | img: "discord.png", 10 | url: "https://discord.com/" 11 | }, 12 | { 13 | id: 2, 14 | img: "youtube.png", 15 | url: "https://www.youtube.com/" 16 | }, 17 | { 18 | id: 3, 19 | img: "twitter.png", 20 | url: "https://twitter.com/" 21 | } 22 | ] 23 | 24 | const footer2 = [ 25 | { 26 | id: 1, 27 | img: "bsc.png" 28 | }, 29 | { 30 | id: 2, 31 | img: "polygonwhite.png" 32 | }, 33 | { 34 | id: 3, 35 | img: "ethereumlogo.png" 36 | } 37 | ] 38 | 39 | 40 | return ( 41 |
42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | n2DMarket 50 | 51 | The blockchain agnostic marketplace. The token with endless posibilities. NFT's are more than just art. Its meant to change the way humans establish ownership of an asset beyond paper. 52 | 53 | 54 | 55 | 56 | Follow Us! 57 |
    58 | {footer1.map((item, idx) => { 59 | return ( 60 | 61 | ); 62 | })} 63 |
64 | 65 | 66 | Integrations 67 |
    68 | {footer2.map((item, idx) => { 69 | return ( 70 | 71 | ); 72 | })} 73 |
74 | 75 | 76 | Our Partners 77 | 82 | 83 |
84 | 85 | ©2022 N2DMarket, All Rights Reserved. 86 | 87 |
88 |
89 |
90 | ); 91 | 92 | } -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/hardhat.config.js: -------------------------------------------------------------------------------- 1 | require("@nomiclabs/hardhat-waffle"); 2 | 3 | module.exports = { 4 | defaultNetwork: "hardhat", 5 | networks: { 6 | hardhat: { 7 | chainId: 31337, 8 | url: "http://node.a3b.io:8545", 9 | accounts: [hhprivKey] 10 | }, 11 | mumbai: { 12 | chainId: 80001, 13 | url: "https://rpc-mumbai.matic.today", 14 | accounts: [ethprivKey] 15 | }, 16 | polygon: { 17 | chainId: 137, 18 | url: "https://rpc-mainnet.maticvigil.com", 19 | accounts: [ethprivKey] 20 | }, 21 | ethereum: { 22 | chainId: 1, 23 | url: "https://main-rpc.linkpool.io", 24 | accounts: [ethprivKey] 25 | }, 26 | binance: { 27 | chainId: 57, 28 | url: "https://bscrpc.com", 29 | accounts: [ethprivKey] 30 | }, 31 | bsctest: { 32 | chainId: 97, 33 | url: "https://data-seed-prebsc-1-s3.binance.org:8545", 34 | accounts: [ethprivKey] 35 | }, 36 | kovan: { 37 | chainId: 42, 38 | url: "https://kovan.infura.io/v3/3cf2d8833a2143b795b7796087fff369", 39 | accounts: [ethprivKey] 40 | } 41 | }, 42 | solidity: { 43 | version: "0.8.4", 44 | settings: { 45 | optimizer: { 46 | enabled: true, 47 | runs: 200 48 | } 49 | } 50 | } 51 | }; 52 | 53 | -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/index.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useEffect, useState } from 'react'; 3 | import axios from 'axios'; 4 | import Web3Modal from "web3modal"; 5 | import { useRouter } from 'next/router'; 6 | import NFTCollection from '../engine/NFTCollection.json' 7 | import Resell from '../engine/Resell.json'; 8 | import { Grid, Card, Text, Button, Row, Spacer, Container } from '@nextui-org/react'; 9 | import { hhresell, hhnftcol, mainnet } from '../engine/configuration'; 10 | import { cipherHH, simpleCrypto } from '../engine/configuration'; 11 | import confetti from 'canvas-confetti'; 12 | import 'sf-font'; 13 | import Carousel from "react-multi-carousel"; 14 | import "react-multi-carousel/lib/styles.css"; 15 | 16 | export default function Home() { 17 | const [hhlist, hhResellNfts] = useState([]) 18 | useEffect(() => { 19 | loadHardHatResell() 20 | }, [hhResellNfts]) 21 | 22 | const handleConfetti = () => { 23 | confetti(); 24 | }; 25 | const router = useRouter() 26 | 27 | async function loadHardHatResell() { 28 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 29 | const key = simpleCrypto.decrypt(cipherHH) 30 | const wallet = new ethers.Wallet(key, provider); 31 | const contract = new ethers.Contract(hhnftcol, NFTCollection, wallet); 32 | const market = new ethers.Contract(hhresell, Resell, wallet); 33 | const itemArray = []; 34 | contract.totalSupply().then(result => { 35 | for (let i = 0; i < result; i++) { 36 | var token = i + 1 37 | var owner = contract.ownerOf(token) 38 | var getOwner = Promise.resolve(owner) 39 | getOwner.then(address => { 40 | if (address == hhresell) { 41 | const rawUri = contract.tokenURI(token) 42 | const Uri = Promise.resolve(rawUri) 43 | const getUri = Uri.then(value => { 44 | let str = value 45 | let cleanUri = str.replace('ipfs://', 'https://ipfs.io/ipfs/') 46 | console.log(cleanUri) 47 | let metadata = axios.get(cleanUri).catch(function (error) { 48 | console.log(error.toJSON()); 49 | }); 50 | return metadata; 51 | }) 52 | getUri.then(value => { 53 | let rawImg = value.data.image 54 | var name = value.data.name 55 | var desc = value.data.description 56 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 57 | const price = market.getPrice(token) 58 | Promise.resolve(price).then(_hex => { 59 | var salePrice = Number(_hex); 60 | var txPrice = salePrice.toString() 61 | Promise.resolve(owner).then(value => { 62 | let ownerW = value; 63 | let outPrice = ethers.utils.formatUnits(salePrice.toString(), 'ether') 64 | let meta = { 65 | name: name, 66 | img: image, 67 | cost: txPrice, 68 | val: outPrice, 69 | tokenId: token, 70 | wallet: ownerW, 71 | desc 72 | } 73 | console.log(meta) 74 | itemArray.push(meta) 75 | }) 76 | }) 77 | }) 78 | }}) 79 | }}) 80 | await new Promise(r => setTimeout(r, 3000)); 81 | hhResellNfts(itemArray) 82 | } 83 | 84 | const responsive = { 85 | desktop: { 86 | breakpoint: { max: 3000, min: 1024 }, 87 | items: 1, 88 | slidesToSlide: 1 89 | }, 90 | tablet: { 91 | breakpoint: { max: 1024, min: 464 }, 92 | items: 2, 93 | slidesToSlide: 2 94 | }, 95 | mobile: { 96 | breakpoint: { max: 464, min: 0 }, 97 | items: 1, 98 | slidesToSlide: 1 99 | } 100 | }; 101 | 102 | return ( 103 |
104 |
105 | 106 | 107 | Top Collections 108 | 123 | { 124 | hhlist.map((nft, i) => ( 125 |
126 | 127 |
128 | )) 129 | } 130 |
131 |
132 |
133 |
134 | 135 | 136 | Latest NFT's 137 | 138 | 139 | { 140 | hhlist.slice(0, 9).map((nft, id) => { 141 | async function buylistNft() { 142 | const web3Modal = new Web3Modal() 143 | const connection = await web3Modal.connect() 144 | const provider = new ethers.providers.Web3Provider(connection) 145 | const signer = provider.getSigner() 146 | const contract = new ethers.Contract(hhresell, Resell, signer) 147 | const transaction = await contract.buyNft(nft.tokenId, { value: nft.cost }) 148 | await transaction.wait() 149 | router.push('/portal') 150 | } 151 | return ( 152 | 153 | 154 | {nft.name} Token-{nft.tokenId} 162 | 163 | 167 | 168 | 169 | 170 | {nft.desc} 171 | {nft.val} 172 | 173 | 174 | 175 | 176 | 177 | ) 178 | }) 179 | } 180 | 181 | 182 | 183 |
184 | ) 185 | } -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/portal.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useState, useEffect } from 'react'; 3 | import Web3Modal from "web3modal"; 4 | import { useRouter } from 'next/router'; 5 | import Resell from '../engine/Resell.json'; 6 | import NFTCollection from '../engine/NFTCollection.json'; 7 | import { Card, Button, Input, Col, Row, Spacer, Container, Text, Grid } from '@nextui-org/react'; 8 | import axios from 'axios'; 9 | import 'sf-font'; 10 | import Web3 from 'web3'; 11 | import { hhresell, hhnftcol, mainnet, cipherHH, simpleCrypto } from '../engine/configuration'; 12 | 13 | 14 | export default function Sell() { 15 | const [user, getUser] = useState([]) 16 | const [resalePrice, updateresalePrice] = useState({ price: ''}) 17 | const [nfts, setNfts] = useState([]) 18 | const [loadingState, setLoadingState] = useState('not-loaded') 19 | useEffect(() => { 20 | connectUser(); 21 | getWalletNFTs() 22 | }, [setNfts,getUser]) 23 | const router = useRouter() 24 | 25 | async function connectUser() { 26 | if (window.ethereum) { 27 | var web3 = new Web3(window.ethereum); 28 | await window.ethereum.send('eth_requestAccounts'); 29 | var accounts = await web3.eth.getAccounts(); 30 | var account = accounts[0]; 31 | } 32 | getUser(account) 33 | } 34 | 35 | async function getWalletNFTs() { 36 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 37 | const key = simpleCrypto.decrypt(cipherHH) 38 | const wallet = new ethers.Wallet(key, provider); 39 | const contract = new ethers.Contract(hhnftcol, NFTCollection, wallet); 40 | const itemArray = []; 41 | contract.totalSupply().then(result => { 42 | for (let i = 0; i < result; i++) { 43 | var token = i + 1 44 | const owner = contract.ownerOf(token).catch(function (error) { 45 | console.log("tokens filtered"); 46 | }); 47 | const rawUri = contract.tokenURI(token).catch(function (error) { 48 | console.log("tokens filtered"); 49 | }); 50 | const Uri = Promise.resolve(rawUri) 51 | const getUri = Uri.then(value => { 52 | var cleanUri = value.replace('ipfs://', 'https://ipfs.io/ipfs/') 53 | let metadata = axios.get(cleanUri).catch(function (error) { 54 | console.log(error.toJSON()); 55 | }); 56 | return metadata; 57 | }) 58 | getUri.then(value => { 59 | let rawImg = value.data.image 60 | var name = value.data.name 61 | var desc = value.data.description 62 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 63 | Promise.resolve(owner).then(value => { 64 | let ownerW = value; 65 | let meta = { 66 | name: name, 67 | img: image, 68 | tokenId: token, 69 | wallet: ownerW, 70 | desc, 71 | } 72 | console.log(meta) 73 | itemArray.push(meta) 74 | }) 75 | }) 76 | } 77 | }) 78 | await new Promise(r => setTimeout(r, 3000)); 79 | setNfts(itemArray) 80 | setLoadingState('loaded'); 81 | } 82 | 83 | if (loadingState === 'loaded' && !nfts.length) 84 | return ( 85 | 86 | 87 | 88 | No NFT's Found, Connect Wallet 89 | 90 | 91 | 92 | 93 | ) 94 | return ( 95 |
96 | 97 | 98 | 99 | NFT's in Wallet {user} 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | {nfts.map((nft, i) => { 108 | var owner = user 109 | if (owner.indexOf(nft.wallet) !== -1) { 110 | async function executeRelist() { 111 | const { price } = resalePrice 112 | if (!price) return 113 | try { 114 | relistNFT() 115 | } catch (error) { 116 | console.log('Transaction Failed', error) 117 | } 118 | } 119 | async function relistNFT() { 120 | const web3Modal = new Web3Modal() 121 | const connection = await web3Modal.connect() 122 | const provider = new ethers.providers.Web3Provider(connection) 123 | const signer = provider.getSigner() 124 | const price = ethers.utils.parseUnits(resalePrice.price, 'ether') 125 | const contractnft = new ethers.Contract(hhnftcol, NFTCollection, signer); 126 | await contractnft.setApprovalForAll(hhresell, true); 127 | let contract = new ethers.Contract(hhresell, Resell, signer) 128 | let listingFee = await contract.getListingFee() 129 | listingFee = listingFee.toString() 130 | let transaction = await contract.listSale(nft.tokenId, price, { value: listingFee }) 131 | await transaction.wait() 132 | router.push('/') 133 | } 134 | return ( 135 | 136 | 137 | 138 | 139 | 140 |

Owned by You

141 | {nft.name} Token-{nft.tokenId} 142 | {nft.desc} 143 | updateresalePrice({ ...resalePrice, price: e.target.value })} 148 | /> 149 | 150 |
151 |
152 |
153 |
154 | ) 155 | }})} 156 |
157 |
158 |
159 | ) 160 | } -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/bsc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/bsc.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/chainagnostic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/chainagnostic.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/discord.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/discord.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/discordlogo.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/discordlogo.PNG -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/ethereumlogo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/ethereumlogo.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/n2DMarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/n2DMarket.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/n2dr-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/n2dr-logo.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/polygonwhite.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/polygonwhite.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/twitter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/twitter.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/web3logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/web3logo.png -------------------------------------------------------------------------------- /Part4-RelistNFT-Buy-Sell/public/youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/Part4-RelistNFT-Buy-Sell/public/youtube.png -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/Market.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "uint256", 8 | "name": "itemId", 9 | "type": "uint256" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "nftContract", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | }, 23 | { 24 | "indexed": false, 25 | "internalType": "address", 26 | "name": "seller", 27 | "type": "address" 28 | }, 29 | { 30 | "indexed": false, 31 | "internalType": "address", 32 | "name": "owner", 33 | "type": "address" 34 | }, 35 | { 36 | "indexed": false, 37 | "internalType": "uint256", 38 | "name": "price", 39 | "type": "uint256" 40 | }, 41 | { 42 | "indexed": false, 43 | "internalType": "bool", 44 | "name": "sold", 45 | "type": "bool" 46 | } 47 | ], 48 | "name": "VaultItemCreated", 49 | "type": "event" 50 | }, 51 | { 52 | "inputs": [ 53 | { 54 | "internalType": "address", 55 | "name": "nftContract", 56 | "type": "address" 57 | }, 58 | { 59 | "internalType": "uint256", 60 | "name": "tokenId", 61 | "type": "uint256" 62 | }, 63 | { 64 | "internalType": "uint256", 65 | "name": "price", 66 | "type": "uint256" 67 | } 68 | ], 69 | "name": "createVaultItem", 70 | "outputs": [], 71 | "stateMutability": "payable", 72 | "type": "function" 73 | }, 74 | { 75 | "inputs": [ 76 | { 77 | "internalType": "address", 78 | "name": "nftContract", 79 | "type": "address" 80 | }, 81 | { 82 | "internalType": "uint256", 83 | "name": "itemId", 84 | "type": "uint256" 85 | } 86 | ], 87 | "name": "n2DMarketSale", 88 | "outputs": [], 89 | "stateMutability": "payable", 90 | "type": "function" 91 | }, 92 | { 93 | "inputs": [], 94 | "stateMutability": "nonpayable", 95 | "type": "constructor" 96 | }, 97 | { 98 | "inputs": [], 99 | "name": "getAvailableNft", 100 | "outputs": [ 101 | { 102 | "components": [ 103 | { 104 | "internalType": "uint256", 105 | "name": "itemId", 106 | "type": "uint256" 107 | }, 108 | { 109 | "internalType": "address", 110 | "name": "nftContract", 111 | "type": "address" 112 | }, 113 | { 114 | "internalType": "uint256", 115 | "name": "tokenId", 116 | "type": "uint256" 117 | }, 118 | { 119 | "internalType": "address payable", 120 | "name": "seller", 121 | "type": "address" 122 | }, 123 | { 124 | "internalType": "address payable", 125 | "name": "owner", 126 | "type": "address" 127 | }, 128 | { 129 | "internalType": "uint256", 130 | "name": "price", 131 | "type": "uint256" 132 | }, 133 | { 134 | "internalType": "bool", 135 | "name": "sold", 136 | "type": "bool" 137 | } 138 | ], 139 | "internalType": "struct n2DMarket.VaultItem[]", 140 | "name": "", 141 | "type": "tuple[]" 142 | } 143 | ], 144 | "stateMutability": "view", 145 | "type": "function" 146 | }, 147 | { 148 | "inputs": [], 149 | "name": "getMyMarketNfts", 150 | "outputs": [ 151 | { 152 | "components": [ 153 | { 154 | "internalType": "uint256", 155 | "name": "itemId", 156 | "type": "uint256" 157 | }, 158 | { 159 | "internalType": "address", 160 | "name": "nftContract", 161 | "type": "address" 162 | }, 163 | { 164 | "internalType": "uint256", 165 | "name": "tokenId", 166 | "type": "uint256" 167 | }, 168 | { 169 | "internalType": "address payable", 170 | "name": "seller", 171 | "type": "address" 172 | }, 173 | { 174 | "internalType": "address payable", 175 | "name": "owner", 176 | "type": "address" 177 | }, 178 | { 179 | "internalType": "uint256", 180 | "name": "price", 181 | "type": "uint256" 182 | }, 183 | { 184 | "internalType": "bool", 185 | "name": "sold", 186 | "type": "bool" 187 | } 188 | ], 189 | "internalType": "struct n2DMarket.VaultItem[]", 190 | "name": "", 191 | "type": "tuple[]" 192 | } 193 | ], 194 | "stateMutability": "view", 195 | "type": "function" 196 | }, 197 | { 198 | "inputs": [], 199 | "name": "getMyNft", 200 | "outputs": [ 201 | { 202 | "components": [ 203 | { 204 | "internalType": "uint256", 205 | "name": "itemId", 206 | "type": "uint256" 207 | }, 208 | { 209 | "internalType": "address", 210 | "name": "nftContract", 211 | "type": "address" 212 | }, 213 | { 214 | "internalType": "uint256", 215 | "name": "tokenId", 216 | "type": "uint256" 217 | }, 218 | { 219 | "internalType": "address payable", 220 | "name": "seller", 221 | "type": "address" 222 | }, 223 | { 224 | "internalType": "address payable", 225 | "name": "owner", 226 | "type": "address" 227 | }, 228 | { 229 | "internalType": "uint256", 230 | "name": "price", 231 | "type": "uint256" 232 | }, 233 | { 234 | "internalType": "bool", 235 | "name": "sold", 236 | "type": "bool" 237 | } 238 | ], 239 | "internalType": "struct n2DMarket.VaultItem[]", 240 | "name": "", 241 | "type": "tuple[]" 242 | } 243 | ], 244 | "stateMutability": "view", 245 | "type": "function" 246 | }, 247 | { 248 | "inputs": [], 249 | "name": "listingFee", 250 | "outputs": [ 251 | { 252 | "internalType": "uint256", 253 | "name": "", 254 | "type": "uint256" 255 | } 256 | ], 257 | "stateMutability": "view", 258 | "type": "function" 259 | } 260 | ] -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/N2D-Market-CreateNFT-SmartContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT OR Apache-2.0 2 | 3 | /* 4 | N2D Marketplace Create NFT Smart Contract 5 | 6 | Follow/Subscribe Youtube, Github, IM, Tiktok 7 | for more amazing content!! 8 | @Net2Dev 9 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗ 10 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║ 11 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝ 12 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░ 13 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░ 14 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░ 15 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL 16 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE 17 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY 18 | OTHER USE. THIS IS TRAINING/EDUCATIONAL 19 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE 20 | TERMS SPECIFIED ABOVE. 21 | 22 | Revision v2 23 | 24 | - Added minting fee balance withdraw function 25 | 26 | */ 27 | 28 | pragma solidity ^0.8.4; 29 | 30 | import "@openzeppelin/contracts/utils/Counters.sol"; 31 | import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; 32 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 33 | import "@openzeppelin/contracts/access/Ownable.sol"; 34 | 35 | contract N2DNFT is ERC721URIStorage, Ownable { 36 | using Counters for Counters.Counter; 37 | Counters.Counter public _tokenIds; 38 | address contractAddress; 39 | uint256 public cost = 0.0075 ether; 40 | 41 | constructor(address marketContract) ERC721("n2DMarket", "N2DM") { 42 | contractAddress = marketContract; 43 | } 44 | 45 | function createNFT(string memory tokenURI) public returns (uint) { 46 | _tokenIds.increment(); 47 | uint256 newItemId = _tokenIds.current(); 48 | _mint(msg.sender, newItemId); 49 | _setTokenURI(newItemId, tokenURI); 50 | setApprovalForAll(contractAddress, true); 51 | return newItemId; 52 | } 53 | 54 | function mintNFT(string memory tokenURI) public payable returns (uint) { 55 | require(msg.value == cost, "Need to send 0.075 ether!"); 56 | _tokenIds.increment(); 57 | uint256 newItemId = _tokenIds.current(); 58 | _mint(msg.sender, newItemId); 59 | _setTokenURI(newItemId, tokenURI); 60 | setApprovalForAll(contractAddress, true); 61 | return newItemId; 62 | } 63 | 64 | function withdraw() public payable onlyOwner() { 65 | require(payable(msg.sender).send(address(this).balance)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/N2D-Market-SellCreatedNFT-SmartContract.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT LICENSE 2 | 3 | /* 4 | N2D Marketplace Sell Created NFT Smart Contract 5 | 6 | Follow/Subscribe Youtube, Github, IM, Tiktok 7 | for more amazing content!! 8 | @Net2Dev 9 | ███╗░░██╗███████╗████████╗██████╗░██████╗░███████╗██╗░░░██╗ 10 | ████╗░██║██╔════╝╚══██╔══╝╚════██╗██╔══██╗██╔════╝██║░░░██║ 11 | ██╔██╗██║█████╗░░░░░██║░░░░░███╔═╝██║░░██║█████╗░░╚██╗░██╔╝ 12 | ██║╚████║██╔══╝░░░░░██║░░░██╔══╝░░██║░░██║██╔══╝░░░╚████╔╝░ 13 | ██║░╚███║███████╗░░░██║░░░███████╗██████╔╝███████╗░░╚██╔╝░░ 14 | ╚═╝░░╚══╝╚══════╝░░░╚═╝░░░╚══════╝╚═════╝░╚══════╝░░░╚═╝░░░ 15 | THIS CONTRACT IS AVAILABLE FOR EDUCATIONAL 16 | PURPOSES ONLY. YOU ARE SOLELY REPONSIBLE 17 | FOR ITS USE. I AM NOT RESPONSIBLE FOR ANY 18 | OTHER USE. THIS IS TRAINING/EDUCATIONAL 19 | MATERIAL. ONLY USE IT IF YOU AGREE TO THE 20 | TERMS SPECIFIED ABOVE. 21 | 22 | Revision v2 23 | 24 | - Added listing and minting fee balance 25 | withdraw function. 26 | */ 27 | 28 | pragma solidity ^0.8.4; 29 | 30 | import "@openzeppelin/contracts/utils/Counters.sol"; 31 | import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; 32 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 33 | import "@openzeppelin/contracts/access/Ownable.sol"; 34 | 35 | 36 | contract n2DMarket is ReentrancyGuard, Ownable { 37 | using Counters for Counters.Counter; 38 | Counters.Counter private _itemIds; 39 | Counters.Counter private _itemsSold; 40 | 41 | address payable holder; 42 | uint256 listingFee = 0.0025 ether; 43 | uint256 mintingFee = 0.0075 ether; 44 | 45 | constructor() { 46 | holder = payable(msg.sender); 47 | } 48 | 49 | struct VaultItem { 50 | uint itemId; 51 | address nftContract; 52 | uint256 tokenId; 53 | address payable seller; 54 | address payable holder; 55 | uint256 price; 56 | bool sold; 57 | } 58 | 59 | mapping(uint256 => VaultItem) private idToVaultItem; 60 | 61 | event VaultItemCreated ( 62 | uint indexed itemId, 63 | address indexed nftContract, 64 | uint256 indexed tokenId, 65 | address seller, 66 | address holder, 67 | uint256 price, 68 | bool sold 69 | ); 70 | 71 | function getListingFee() public view returns (uint256) { 72 | return listingFee; 73 | } 74 | 75 | function createVaultItem(address nftContract,uint256 tokenId,uint256 price) public payable nonReentrant { 76 | require(price > 0, "Price cannot be zero"); 77 | require(msg.value == listingFee, "Price cannot be listing fee"); 78 | _itemIds.increment(); 79 | uint256 itemId = _itemIds.current(); 80 | idToVaultItem[itemId] = VaultItem(itemId,nftContract,tokenId,payable(msg.sender),payable(address(0)),price,false); 81 | IERC721(nftContract).transferFrom(msg.sender, address(this), tokenId); 82 | emit VaultItemCreated(itemId,nftContract,tokenId,msg.sender,address(0),price,false);} 83 | 84 | function n2DMarketSale( 85 | address nftContract,uint256 itemId) public payable nonReentrant { 86 | uint price = idToVaultItem[itemId].price; 87 | uint tokenId = idToVaultItem[itemId].tokenId; 88 | require(msg.value == price, "Not enough balance to complete transaction"); 89 | idToVaultItem[itemId].seller.transfer(msg.value); 90 | IERC721(nftContract).transferFrom(address(this), msg.sender, tokenId); 91 | idToVaultItem[itemId].holder = payable(msg.sender); 92 | idToVaultItem[itemId].sold = true; 93 | _itemsSold.increment(); 94 | payable(holder).transfer(listingFee); 95 | } 96 | 97 | function getAvailableNft() public view returns (VaultItem[] memory) { 98 | uint itemCount = _itemIds.current(); 99 | uint unsoldItemCount = _itemIds.current() - _itemsSold.current(); 100 | uint currentIndex = 0; 101 | 102 | VaultItem[] memory items = new VaultItem[](unsoldItemCount); 103 | for (uint i = 0; i < itemCount; i++) { 104 | if (idToVaultItem[i + 1].holder == address(0)) { 105 | uint currentId = i + 1; 106 | VaultItem storage currentItem = idToVaultItem[currentId]; 107 | items[currentIndex] = currentItem; 108 | currentIndex += 1; 109 | } 110 | } 111 | return items; 112 | } 113 | 114 | function getMyNft() public view returns (VaultItem[] memory) { 115 | uint totalItemCount = _itemIds.current(); 116 | uint itemCount = 0; 117 | uint currentIndex = 0; 118 | 119 | for (uint i = 0; i < totalItemCount; i++) { 120 | if (idToVaultItem[i + 1].holder == msg.sender) { 121 | itemCount += 1; 122 | } 123 | } 124 | 125 | VaultItem[] memory items = new VaultItem[](itemCount); 126 | for (uint i = 0; i < totalItemCount; i++) { 127 | if (idToVaultItem[i + 1].holder == msg.sender) { 128 | uint currentId = i + 1; 129 | VaultItem storage currentItem = idToVaultItem[currentId]; 130 | items[currentIndex] = currentItem; 131 | currentIndex += 1; 132 | } 133 | } 134 | return items; 135 | } 136 | 137 | function getMyMarketNfts() public view returns (VaultItem[] memory) { 138 | uint totalItemCount = _itemIds.current(); 139 | uint itemCount = 0; 140 | uint currentIndex = 0; 141 | 142 | for (uint i = 0; i < totalItemCount; i++) { 143 | if (idToVaultItem[i + 1].seller == msg.sender) { 144 | itemCount += 1; 145 | } 146 | } 147 | 148 | VaultItem[] memory items = new VaultItem[](itemCount); 149 | for (uint i = 0; i < totalItemCount; i++) { 150 | if (idToVaultItem[i + 1].seller == msg.sender) { 151 | uint currentId = i + 1; 152 | VaultItem storage currentItem = idToVaultItem[currentId]; 153 | items[currentIndex] = currentItem; 154 | currentIndex += 1; 155 | } 156 | } 157 | return items; 158 | } 159 | 160 | function withdraw() public payable onlyOwner() { 161 | require(payable(msg.sender).send(address(this).balance)); 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/NFT.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "anonymous": false, 4 | "inputs": [ 5 | { 6 | "indexed": true, 7 | "internalType": "address", 8 | "name": "owner", 9 | "type": "address" 10 | }, 11 | { 12 | "indexed": true, 13 | "internalType": "address", 14 | "name": "approved", 15 | "type": "address" 16 | }, 17 | { 18 | "indexed": true, 19 | "internalType": "uint256", 20 | "name": "tokenId", 21 | "type": "uint256" 22 | } 23 | ], 24 | "name": "Approval", 25 | "type": "event" 26 | }, 27 | { 28 | "anonymous": false, 29 | "inputs": [ 30 | { 31 | "indexed": true, 32 | "internalType": "address", 33 | "name": "owner", 34 | "type": "address" 35 | }, 36 | { 37 | "indexed": true, 38 | "internalType": "address", 39 | "name": "operator", 40 | "type": "address" 41 | }, 42 | { 43 | "indexed": false, 44 | "internalType": "bool", 45 | "name": "approved", 46 | "type": "bool" 47 | } 48 | ], 49 | "name": "ApprovalForAll", 50 | "type": "event" 51 | }, 52 | { 53 | "anonymous": false, 54 | "inputs": [ 55 | { 56 | "indexed": true, 57 | "internalType": "address", 58 | "name": "from", 59 | "type": "address" 60 | }, 61 | { 62 | "indexed": true, 63 | "internalType": "address", 64 | "name": "to", 65 | "type": "address" 66 | }, 67 | { 68 | "indexed": true, 69 | "internalType": "uint256", 70 | "name": "tokenId", 71 | "type": "uint256" 72 | } 73 | ], 74 | "name": "Transfer", 75 | "type": "event" 76 | }, 77 | { 78 | "inputs": [ 79 | { 80 | "internalType": "address", 81 | "name": "to", 82 | "type": "address" 83 | }, 84 | { 85 | "internalType": "uint256", 86 | "name": "tokenId", 87 | "type": "uint256" 88 | } 89 | ], 90 | "name": "approve", 91 | "outputs": [], 92 | "stateMutability": "nonpayable", 93 | "type": "function" 94 | }, 95 | { 96 | "inputs": [ 97 | { 98 | "internalType": "string", 99 | "name": "tokenURI", 100 | "type": "string" 101 | } 102 | ], 103 | "name": "createNFT", 104 | "outputs": [ 105 | { 106 | "internalType": "uint256", 107 | "name": "", 108 | "type": "uint256" 109 | } 110 | ], 111 | "stateMutability": "nonpayable", 112 | "type": "function" 113 | }, 114 | { 115 | "inputs": [ 116 | { 117 | "internalType": "string", 118 | "name": "tokenURI", 119 | "type": "string" 120 | } 121 | ], 122 | "name": "mintNFT", 123 | "outputs": [ 124 | { 125 | "internalType": "uint256", 126 | "name": "", 127 | "type": "uint256" 128 | } 129 | ], 130 | "stateMutability": "payable", 131 | "type": "function" 132 | }, 133 | { 134 | "inputs": [ 135 | { 136 | "internalType": "address", 137 | "name": "from", 138 | "type": "address" 139 | }, 140 | { 141 | "internalType": "address", 142 | "name": "to", 143 | "type": "address" 144 | }, 145 | { 146 | "internalType": "uint256", 147 | "name": "tokenId", 148 | "type": "uint256" 149 | } 150 | ], 151 | "name": "safeTransferFrom", 152 | "outputs": [], 153 | "stateMutability": "nonpayable", 154 | "type": "function" 155 | }, 156 | { 157 | "inputs": [ 158 | { 159 | "internalType": "address", 160 | "name": "from", 161 | "type": "address" 162 | }, 163 | { 164 | "internalType": "address", 165 | "name": "to", 166 | "type": "address" 167 | }, 168 | { 169 | "internalType": "uint256", 170 | "name": "tokenId", 171 | "type": "uint256" 172 | }, 173 | { 174 | "internalType": "bytes", 175 | "name": "data", 176 | "type": "bytes" 177 | } 178 | ], 179 | "name": "safeTransferFrom", 180 | "outputs": [], 181 | "stateMutability": "nonpayable", 182 | "type": "function" 183 | }, 184 | { 185 | "inputs": [ 186 | { 187 | "internalType": "address", 188 | "name": "operator", 189 | "type": "address" 190 | }, 191 | { 192 | "internalType": "bool", 193 | "name": "approved", 194 | "type": "bool" 195 | } 196 | ], 197 | "name": "setApprovalForAll", 198 | "outputs": [], 199 | "stateMutability": "nonpayable", 200 | "type": "function" 201 | }, 202 | { 203 | "inputs": [ 204 | { 205 | "internalType": "address", 206 | "name": "from", 207 | "type": "address" 208 | }, 209 | { 210 | "internalType": "address", 211 | "name": "to", 212 | "type": "address" 213 | }, 214 | { 215 | "internalType": "uint256", 216 | "name": "tokenId", 217 | "type": "uint256" 218 | } 219 | ], 220 | "name": "transferFrom", 221 | "outputs": [], 222 | "stateMutability": "nonpayable", 223 | "type": "function" 224 | }, 225 | { 226 | "inputs": [ 227 | { 228 | "internalType": "address", 229 | "name": "marketContract", 230 | "type": "address" 231 | } 232 | ], 233 | "stateMutability": "nonpayable", 234 | "type": "constructor" 235 | }, 236 | { 237 | "inputs": [], 238 | "name": "_tokenIds", 239 | "outputs": [ 240 | { 241 | "internalType": "uint256", 242 | "name": "_value", 243 | "type": "uint256" 244 | } 245 | ], 246 | "stateMutability": "view", 247 | "type": "function" 248 | }, 249 | { 250 | "inputs": [ 251 | { 252 | "internalType": "address", 253 | "name": "owner", 254 | "type": "address" 255 | } 256 | ], 257 | "name": "balanceOf", 258 | "outputs": [ 259 | { 260 | "internalType": "uint256", 261 | "name": "", 262 | "type": "uint256" 263 | } 264 | ], 265 | "stateMutability": "view", 266 | "type": "function" 267 | }, 268 | { 269 | "inputs": [], 270 | "name": "cost", 271 | "outputs": [ 272 | { 273 | "internalType": "uint256", 274 | "name": "", 275 | "type": "uint256" 276 | } 277 | ], 278 | "stateMutability": "view", 279 | "type": "function" 280 | }, 281 | { 282 | "inputs": [ 283 | { 284 | "internalType": "uint256", 285 | "name": "tokenId", 286 | "type": "uint256" 287 | } 288 | ], 289 | "name": "getApproved", 290 | "outputs": [ 291 | { 292 | "internalType": "address", 293 | "name": "", 294 | "type": "address" 295 | } 296 | ], 297 | "stateMutability": "view", 298 | "type": "function" 299 | }, 300 | { 301 | "inputs": [ 302 | { 303 | "internalType": "address", 304 | "name": "owner", 305 | "type": "address" 306 | }, 307 | { 308 | "internalType": "address", 309 | "name": "operator", 310 | "type": "address" 311 | } 312 | ], 313 | "name": "isApprovedForAll", 314 | "outputs": [ 315 | { 316 | "internalType": "bool", 317 | "name": "", 318 | "type": "bool" 319 | } 320 | ], 321 | "stateMutability": "view", 322 | "type": "function" 323 | }, 324 | { 325 | "inputs": [], 326 | "name": "name", 327 | "outputs": [ 328 | { 329 | "internalType": "string", 330 | "name": "", 331 | "type": "string" 332 | } 333 | ], 334 | "stateMutability": "view", 335 | "type": "function" 336 | }, 337 | { 338 | "inputs": [ 339 | { 340 | "internalType": "uint256", 341 | "name": "tokenId", 342 | "type": "uint256" 343 | } 344 | ], 345 | "name": "ownerOf", 346 | "outputs": [ 347 | { 348 | "internalType": "address", 349 | "name": "", 350 | "type": "address" 351 | } 352 | ], 353 | "stateMutability": "view", 354 | "type": "function" 355 | }, 356 | { 357 | "inputs": [ 358 | { 359 | "internalType": "bytes4", 360 | "name": "interfaceId", 361 | "type": "bytes4" 362 | } 363 | ], 364 | "name": "supportsInterface", 365 | "outputs": [ 366 | { 367 | "internalType": "bool", 368 | "name": "", 369 | "type": "bool" 370 | } 371 | ], 372 | "stateMutability": "view", 373 | "type": "function" 374 | }, 375 | { 376 | "inputs": [], 377 | "name": "symbol", 378 | "outputs": [ 379 | { 380 | "internalType": "string", 381 | "name": "", 382 | "type": "string" 383 | } 384 | ], 385 | "stateMutability": "view", 386 | "type": "function" 387 | }, 388 | { 389 | "inputs": [ 390 | { 391 | "internalType": "uint256", 392 | "name": "tokenId", 393 | "type": "uint256" 394 | } 395 | ], 396 | "name": "tokenURI", 397 | "outputs": [ 398 | { 399 | "internalType": "string", 400 | "name": "", 401 | "type": "string" 402 | } 403 | ], 404 | "stateMutability": "view", 405 | "type": "function" 406 | } 407 | ] -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/_app.js: -------------------------------------------------------------------------------- 1 | import { createTheme, NextUIProvider } from "@nextui-org/react"; 2 | import 'sf-font'; 3 | import Link from 'next/link' 4 | import { Spacer, Button, Col, Row, Container, Dropdown, Text } from '@nextui-org/react'; 5 | import react from "react"; 6 | import Footer from './footer'; 7 | 8 | const theme = createTheme({ 9 | type: "dark", 10 | theme: { 11 | fontFamily:'SF Pro Display', 12 | colors: { 13 | primaryLight: '$blue200', 14 | primaryLightHover: '$blue300', 15 | primaryLightActive: '$blue400', 16 | primaryLightContrast: '$blue600', 17 | primary: '$purple500', 18 | primaryBorder: '$blue500', 19 | primaryBorderHover: '$blue600', 20 | primarySolidHover: '$blue700', 21 | primarySolidContrast: '$white', 22 | primaryShadow: '$white500', 23 | transparent: '#00000000', 24 | 25 | gradient: 'linear-gradient(112deg, $blue100 -25%, $pink500 -10%, $purple300 90%)', 26 | link: '#5E1DAD', 27 | 28 | myColor: '#00000030' 29 | 30 | }, 31 | space: {}, 32 | fonts: {} 33 | } 34 | }) 35 | 36 | function MyApp({ Component, pageProps }) { 37 | 38 | return( 39 |
40 |
41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 58 | 59 | 60 | 61 | 62 | 72 | 73 | 74 | 75 | 88 | 89 | 90 | 103 | 104 | 105 | 106 | 107 | 108 | 109 |
113 |
114 | 115 | ) 116 | 117 | 118 | } 119 | 120 | export default MyApp 121 | -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/create.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useState } from 'react'; 3 | import { useRouter } from 'next/router'; 4 | import Web3Modal from "web3modal"; 5 | import NFT from '../engine/NFT.json'; 6 | import Market from '../engine/Market.json'; 7 | import { hhnft, hhmarket } from '../engine/configuration'; 8 | import { Card, Button, Input, Col, Row, Spacer, Container, Text, Grid } from '@nextui-org/react'; 9 | import { client } from '../engine/configuration'; 10 | import 'sf-font'; 11 | 12 | export default function createMarket() { 13 | const [fileUrl, setFileUrl] = useState(null) 14 | const [formInput, updateFormInput] = useState({ price: '', name: '', description: '' }) 15 | const router = useRouter() 16 | 17 | async function onChange(e) { 18 | const file = e.target.files[0] 19 | try { 20 | const added = await client.add( 21 | file, 22 | { 23 | progress: (prog) => console.log(`received: ${prog}`) 24 | } 25 | ) 26 | const url = `https://ipfs.infura.io/ipfs/${added.path}` 27 | setFileUrl(url) 28 | } catch (error) { 29 | console.log('Error uploading file: ', error) 30 | } 31 | } 32 | 33 | async function createMarket() { 34 | const { name, description, price } = formInput 35 | if (!name || !description || !price || !fileUrl) return 36 | const data = JSON.stringify({ 37 | name, description, image: fileUrl 38 | }) 39 | try { 40 | const added = await client.add(data) 41 | const url = `https://ipfs.infura.io/ipfs/${added.path}` 42 | createNFT(url) 43 | } catch (error) { 44 | console.log('Error uploading file: ', error) 45 | } 46 | } 47 | 48 | async function createNFT(url) { 49 | const web3Modal = new Web3Modal() 50 | const connection = await web3Modal.connect() 51 | const provider = new ethers.providers.Web3Provider(connection) 52 | const signer = provider.getSigner() 53 | let contract = new ethers.Contract(hhnft, NFT, signer) 54 | let transaction = await contract.createNFT(url) 55 | let tx = await transaction.wait() 56 | let event = tx.events[0] 57 | let value = event.args[2] 58 | let tokenId = value.toNumber() 59 | const price = ethers.utils.parseUnits(formInput.price, 'ether') 60 | contract = new ethers.Contract(hhmarket, Market, signer) 61 | let listingFee = await contract.listingFee() 62 | listingFee = listingFee.toString() 63 | transaction = await contract.createVaultItem(hhnft, tokenId, price, { value: listingFee }) 64 | await transaction.wait() 65 | router.push('/') 66 | } 67 | 68 | async function buyNFT() { 69 | const { name, description } = formInput 70 | if (!name || !description || !fileUrl) return 71 | const data = JSON.stringify({ 72 | name, description, image: fileUrl 73 | }) 74 | try { 75 | const added = await client.add(data) 76 | const url = `https://ipfs.infura.io/ipfs/${added.path}` 77 | mintNFT(url) 78 | } catch (error) { 79 | console.log('Error uploading file: ', error) 80 | } 81 | } 82 | 83 | async function mintNFT(url) { 84 | const web3Modal = new Web3Modal() 85 | const connection = await web3Modal.connect() 86 | const provider = new ethers.providers.Web3Provider(connection) 87 | const signer = provider.getSigner() 88 | let contract = new ethers.Contract(hhnft, NFT, signer) 89 | let cost = await contract.cost() 90 | let transaction = await contract.mintNFT(url, { value: cost }) 91 | await transaction.wait() 92 | router.push('/portal') 93 | } 94 | 95 | return ( 96 |
97 | 98 | 99 | NFT Creator Portal 100 | 101 | 102 | 103 | 104 | 105 | The NFT Marketplace with a Reward. 106 | N2DR IS More Than A Token 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | Select your Preferred Network, Create your Amazing NFT by uploading your art using the simple NFT Dashboard. Simple! 115 | 116 | 117 | 118 | 119 | 120 | Chain-Agnostic Marketplace that allows you to sell your NFT and accept your favorite crypto as payment! No borders, No restrictions. Simple! 121 | 122 | 123 | 124 | 125 | 126 | Create and Sell your NFT in the Marketplace 127 | 128 | 129 | 130 | updateFormInput({ ...formInput, name: e.target.value })} 133 | /> 134 | 135 | 136 | 137 | 138 | updateFormInput({ ...formInput, description: e.target.value })} 141 | /> 142 | 143 | 144 | 145 | 146 | 151 | { 152 | fileUrl && ( 153 | 154 | ) 155 | } 156 | 157 | 158 | 159 | updateFormInput({ ...formInput, price: e.target.value })} 163 | /> 164 | 167 | 170 | 171 | 172 | 173 | 174 | 175 |
176 | ) 177 | } 178 | -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/index.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useEffect, useState } from 'react'; 3 | import axios from 'axios'; 4 | import Web3Modal from "web3modal"; 5 | import { useRouter } from 'next/router'; 6 | import NFTCollection from '../engine/NFTCollection.json' 7 | import Resell from '../engine/Resell.json'; 8 | import Market from '../engine/Market.json'; 9 | import NFT from '../engine/NFT.json'; 10 | import { Grid, Card, Text, Button, Row, Spacer, Container } from '@nextui-org/react'; 11 | import { hhnft, hhmarket, hhresell, hhnftcol, mainnet } from '../engine/configuration'; 12 | import { cipherHH, simpleCrypto } from '../engine/configuration'; 13 | import confetti from 'canvas-confetti'; 14 | import 'sf-font'; 15 | import Carousel from "react-multi-carousel"; 16 | import "react-multi-carousel/lib/styles.css"; 17 | 18 | export default function Home() { 19 | const [hhlist, hhResellNfts] = useState([]) 20 | const [hhnfts, hhsetNfts] = useState([]) 21 | 22 | useEffect(() => { 23 | loadHardHatResell() 24 | loadNewSaleNFTs() 25 | }, [hhResellNfts, hhsetNfts]) 26 | 27 | const handleConfetti = () => { 28 | confetti(); 29 | }; 30 | const router = useRouter() 31 | 32 | async function loadHardHatResell() { 33 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 34 | const key = simpleCrypto.decrypt(cipherHH) 35 | const wallet = new ethers.Wallet(key, provider); 36 | const contract = new ethers.Contract(hhnftcol, NFTCollection, wallet); 37 | const market = new ethers.Contract(hhresell, Resell, wallet); 38 | const itemArray = []; 39 | contract.totalSupply().then(result => { 40 | for (let i = 0; i < result; i++) { 41 | var token = i + 1 42 | var owner = contract.ownerOf(token) 43 | var getOwner = Promise.resolve(owner) 44 | getOwner.then(address => { 45 | if (address == hhresell) { 46 | const rawUri = contract.tokenURI(token) 47 | const Uri = Promise.resolve(rawUri) 48 | const getUri = Uri.then(value => { 49 | let str = value 50 | let cleanUri = str.replace('ipfs://', 'https://ipfs.io/ipfs/') 51 | console.log(cleanUri) 52 | let metadata = axios.get(cleanUri).catch(function (error) { 53 | console.log(error.toJSON()); 54 | }); 55 | return metadata; 56 | }) 57 | getUri.then(value => { 58 | let rawImg = value.data.image 59 | var name = value.data.name 60 | var desc = value.data.description 61 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 62 | const price = market.getPrice(token) 63 | Promise.resolve(price).then(_hex => { 64 | var salePrice = Number(_hex); 65 | var txPrice = salePrice.toString() 66 | Promise.resolve(owner).then(value => { 67 | let ownerW = value; 68 | let outPrice = ethers.utils.formatUnits(salePrice.toString(), 'ether') 69 | let meta = { 70 | name: name, 71 | img: image, 72 | cost: txPrice, 73 | val: outPrice, 74 | tokenId: token, 75 | wallet: ownerW, 76 | desc 77 | } 78 | console.log(meta) 79 | itemArray.push(meta) 80 | }) 81 | }) 82 | }) 83 | }}) 84 | }}) 85 | await new Promise(r => setTimeout(r, 3000)); 86 | hhResellNfts(itemArray) 87 | } 88 | 89 | async function loadNewSaleNFTs() { 90 | const hhPrivkey = simpleCrypto.decrypt(cipherHH) 91 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 92 | const wallet = new ethers.Wallet(hhPrivkey, provider); 93 | const tokenContract = new ethers.Contract(hhnft, NFT, wallet) 94 | const marketContract = new ethers.Contract(hhmarket, Market, wallet) 95 | const data = await marketContract.getAvailableNft() 96 | const items = await Promise.all(data.map(async i => { 97 | const tokenUri = await tokenContract.tokenURI(i.tokenId) 98 | const meta = await axios.get(tokenUri) 99 | let price = ethers.utils.formatUnits(i.price.toString(), 'ether') 100 | let item = { 101 | price, 102 | tokenId: i.tokenId.toNumber(), 103 | seller: i.seller, 104 | owner: i.owner, 105 | image: meta.data.image, 106 | name: meta.data.name, 107 | description: meta.data.description, 108 | } 109 | return item 110 | })) 111 | hhsetNfts(items) 112 | } 113 | 114 | async function buyNewNft(nft) { 115 | const web3Modal = new Web3Modal() 116 | const connection = await web3Modal.connect() 117 | const provider = new ethers.providers.Web3Provider(connection) 118 | const signer = provider.getSigner() 119 | const contract = new ethers.Contract(hhmarket, Market, signer) 120 | const price = ethers.utils.parseUnits(nft.price.toString(), 'ether') 121 | const transaction = await contract.n2DMarketSale(hhnft, nft.tokenId, { 122 | value: price 123 | }) 124 | await transaction.wait() 125 | loadNewSaleNFTs() 126 | } 127 | 128 | const responsive = { 129 | desktop: { 130 | breakpoint: { max: 3000, min: 1024 }, 131 | items: 1, 132 | slidesToSlide: 1 133 | }, 134 | tablet: { 135 | breakpoint: { max: 1024, min: 464 }, 136 | items: 2, 137 | slidesToSlide: 2 138 | }, 139 | mobile: { 140 | breakpoint: { max: 464, min: 0 }, 141 | items: 1, 142 | slidesToSlide: 1 143 | } 144 | }; 145 | 146 | return ( 147 |
148 |
149 | 150 | 151 | Top Collections 152 | 167 | { 168 | hhlist.map((nft, i) => ( 169 |
170 | 171 |
172 | )) 173 | } 174 |
175 |
176 |
177 |
178 | 179 | 180 | Latest NFT's 181 | 182 | 183 | { 184 | hhlist.slice(0, 9).map((nft, id) => { 185 | async function buylistNft() { 186 | const web3Modal = new Web3Modal() 187 | const connection = await web3Modal.connect() 188 | const provider = new ethers.providers.Web3Provider(connection) 189 | const signer = provider.getSigner() 190 | const contract = new ethers.Contract(hhresell, Resell, signer) 191 | const transaction = await contract.buyNft(nft.tokenId, { value: nft.cost }) 192 | await transaction.wait() 193 | router.push('/portal') 194 | } 195 | return ( 196 | 197 | 198 | {nft.name} Token-{nft.tokenId} 206 | 207 | 211 | 212 | 213 | 214 | {nft.desc} 215 | {nft.val} 216 | 217 | 218 | 219 | 220 | 221 | ) 222 | }) 223 | } 224 | 225 | 226 | 227 | 228 | 229 | Latest NFT's on 230 | 231 | 232 | { 233 | hhnfts.slice(0, 4).map((nft, i) => ( 234 | 235 | 236 | {nft.name} 244 | 245 | 249 | 250 | 251 | 252 | {nft.description} 253 | {nft.price} 254 | 255 | 256 | 257 | 258 | 259 | )) 260 | } 261 | 262 | 263 |
264 | ) 265 | } -------------------------------------------------------------------------------- /Part5-Create-and-Sell-NFT-App/portal.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useState, useEffect } from 'react'; 3 | import Web3Modal from "web3modal"; 4 | import { useRouter } from 'next/router'; 5 | import Resell from '../engine/Resell.json'; 6 | import NFTCollection from '../engine/NFTCollection.json'; 7 | import NFT from '../engine/NFT.json'; 8 | import { Card, Button, Input, Col, Row, Spacer, Container, Text, Grid } from '@nextui-org/react'; 9 | import axios from 'axios'; 10 | import 'sf-font'; 11 | import Web3 from 'web3'; 12 | import { hhnft, hhresell, hhnftcol, mainnet, cipherHH, simpleCrypto } from '../engine/configuration'; 13 | 14 | export default function Sell() { 15 | const [user, getUser] = useState([]) 16 | const [created, getCreated] = useState([]) 17 | const [resalePrice, updateresalePrice] = useState({ price: ''}) 18 | const [nfts, setNfts] = useState([]) 19 | const [loadingState, setLoadingState] = useState('not-loaded') 20 | useEffect(() => { 21 | connectUser(); 22 | getWalletNFTs(); 23 | getCreatedNFTs(); 24 | }, [setNfts,getUser, getCreated]) 25 | const router = useRouter() 26 | 27 | async function connectUser() { 28 | if (window.ethereum) { 29 | var web3 = new Web3(window.ethereum); 30 | await window.ethereum.send('eth_requestAccounts'); 31 | var accounts = await web3.eth.getAccounts(); 32 | var account = accounts[0]; 33 | } 34 | getUser(account) 35 | } 36 | 37 | async function getWalletNFTs() { 38 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 39 | const key = simpleCrypto.decrypt(cipherHH) 40 | const wallet = new ethers.Wallet(key, provider); 41 | const contract = new ethers.Contract(hhnftcol, NFTCollection, wallet); 42 | const itemArray = []; 43 | contract.totalSupply().then(result => { 44 | for (let i = 0; i < result; i++) { 45 | var token = i + 1 46 | const owner = contract.ownerOf(token).catch(function (error) { 47 | console.log("tokens filtered"); 48 | }); 49 | const rawUri = contract.tokenURI(token).catch(function (error) { 50 | console.log("tokens filtered"); 51 | }); 52 | const Uri = Promise.resolve(rawUri) 53 | const getUri = Uri.then(value => { 54 | var cleanUri = value.replace('ipfs://', 'https://ipfs.io/ipfs/') 55 | let metadata = axios.get(cleanUri).catch(function (error) { 56 | console.log(error.toJSON()); 57 | }); 58 | return metadata; 59 | }) 60 | getUri.then(value => { 61 | let rawImg = value.data.image 62 | var name = value.data.name 63 | var desc = value.data.description 64 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 65 | Promise.resolve(owner).then(value => { 66 | let ownerW = value; 67 | let meta = { 68 | name: name, 69 | img: image, 70 | tokenId: token, 71 | wallet: ownerW, 72 | desc, 73 | } 74 | console.log(meta) 75 | itemArray.push(meta) 76 | }) 77 | }) 78 | } 79 | }) 80 | await new Promise(r => setTimeout(r, 3000)); 81 | setNfts(itemArray) 82 | setLoadingState('loaded'); 83 | } 84 | 85 | async function getCreatedNFTs() { 86 | const provider = new ethers.providers.JsonRpcProvider(mainnet) 87 | const key = simpleCrypto.decrypt(cipherHH) 88 | const wallet = new ethers.Wallet(key, provider); 89 | const contract = new ethers.Contract(hhnft, NFT, wallet); 90 | const itemArray = []; 91 | contract._tokenIds().then(result => { 92 | for (let i = 0; i < result; i++) { 93 | var token = i + 1 94 | const owner = contract.ownerOf(token).catch(function (error) { 95 | console.log("tokens filtered"); 96 | }); 97 | const rawUri = contract.tokenURI(token).catch(function (error) { 98 | console.log("tokens filtered"); 99 | }); 100 | const Uri = Promise.resolve(rawUri) 101 | const getUri = Uri.then(value => { 102 | var cleanUri = value.replace('ipfs://', 'https://ipfs.io/ipfs/') 103 | let metadata = axios.get(cleanUri).catch(function (error) { 104 | console.log(error.toJSON()); 105 | }); 106 | return metadata; 107 | }) 108 | getUri.then(value => { 109 | let rawImg = value.data.image 110 | var name = value.data.name 111 | var desc = value.data.description 112 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 113 | Promise.resolve(owner).then(value => { 114 | let ownerW = value; 115 | let meta = { 116 | name: name, 117 | img: image, 118 | tokenId: token, 119 | wallet: ownerW, 120 | desc, 121 | } 122 | console.log(meta) 123 | itemArray.push(meta) 124 | }) 125 | }) 126 | } 127 | }) 128 | await new Promise(r => setTimeout(r, 3000)); 129 | getCreated(itemArray) 130 | setLoadingState('loaded'); 131 | } 132 | 133 | if (loadingState === 'loaded' && !nfts.length) 134 | return ( 135 | 136 | 137 | 138 | No NFT's Found, Connect Wallet 139 | 140 | 141 | 142 | 143 | ) 144 | return ( 145 |
146 | 147 | 148 | 149 | NFT's in Wallet {user} 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | {nfts.map((nft, i) => { 159 | var owner = user 160 | if (owner.indexOf(nft.wallet) !== -1) { 161 | async function executeRelist() { 162 | const { price } = resalePrice 163 | if (!price) return 164 | try { 165 | relistNFT() 166 | } catch (error) { 167 | console.log('Transaction Failed', error) 168 | } 169 | } 170 | async function relistNFT() { 171 | const web3Modal = new Web3Modal() 172 | const connection = await web3Modal.connect() 173 | const provider = new ethers.providers.Web3Provider(connection) 174 | const signer = provider.getSigner() 175 | const price = ethers.utils.parseUnits(resalePrice.price, 'ether') 176 | const contractnft = new ethers.Contract(hhnftcol, NFTCollection, signer); 177 | await contractnft.setApprovalForAll(hhresell, true); 178 | let contract = new ethers.Contract(hhresell, Resell, signer) 179 | let listingFee = await contract.getListingFee() 180 | listingFee = listingFee.toString() 181 | let transaction = await contract.listSale(nft.tokenId, price, { value: listingFee }) 182 | await transaction.wait() 183 | router.push('/') 184 | } 185 | return ( 186 | 187 | 188 | 189 | 190 | 191 |

Owned by You

192 | {nft.name} Token-{nft.tokenId} 193 | {nft.desc} 194 | updateresalePrice({ ...resalePrice, price: e.target.value })} 199 | /> 200 | 201 |
202 |
203 |
204 |
205 | ) 206 | }})} 207 |
208 |
209 |
210 | 211 | 212 | Created NFT's in Wallet 213 | 214 | 215 | {created.map((nft, i) => { 216 | var owner = user 217 | if (owner.indexOf(nft.wallet) !== -1) { 218 | return ( 219 | 220 | 221 | 222 | 223 | 224 |

Owned by You

225 | {nft.name} Token-{nft.tokenId} 226 | {nft.desc} 227 |
228 |
229 |
230 |
231 | ) 232 | }})} 233 |
234 |
235 |
236 |
237 | ) 238 | } -------------------------------------------------------------------------------- /Part6-Final-Multichain-Integration/engine/chainchange.js: -------------------------------------------------------------------------------- 1 | export async function bscChain() { 2 | try { 3 | await ethereum.request({ 4 | method: 'wallet_switchEthereumChain', 5 | params: [{ chainId: '0x38' }], 6 | }); 7 | } catch (switchError) { 8 | if (switchError.code === 4902) { 9 | try { 10 | await window.ethereum.request({ 11 | method: 'wallet_addEthereumChain', 12 | params: [{ 13 | chainId: '0x38', 14 | chainName: 'Binance Smart Chain', 15 | nativeCurrency: { 16 | name: 'BNB', 17 | symbol: 'BNB', 18 | decimals: 18, 19 | }, 20 | rpcUrls: ['https://bsc-dataseed2.defibit.io'], 21 | blockExplorerUrls: ['https://bscscan.com/'], 22 | }] 23 | }) 24 | } catch (addError) { 25 | console.log('Error adding Chain'); 26 | } 27 | } 28 | } 29 | } 30 | export async function polyChain() { 31 | try { 32 | await ethereum.request({ 33 | method: 'wallet_switchEthereumChain', 34 | params: [{ chainId: '0x89' }], 35 | }); 36 | } catch (switchError) { 37 | if (switchError.code === 4902) { 38 | try { 39 | await window.ethereum.request({ 40 | method: 'wallet_addEthereumChain', 41 | params: [{ 42 | chainId: '0x89', 43 | chainName: 'Polygon', 44 | nativeCurrency: { 45 | name: 'MATIC', 46 | symbol: 'MATIC', 47 | decimals: 18, 48 | }, 49 | rpcUrls: ['https://matic-mainnet.chainstacklabs.com'], 50 | blockExplorerUrls: ['https://polygonscan.com/'], 51 | }] 52 | }) 53 | } catch (addError) { 54 | console.log('Error adding Chain'); 55 | } 56 | } 57 | } 58 | } 59 | 60 | export async function ethChain() { 61 | try { 62 | await ethereum.request({ 63 | method: 'wallet_switchEthereumChain', 64 | params: [{ chainId: '0x1' }], 65 | }); 66 | } catch (switchError) { 67 | console.log('Wallet Not Connected') 68 | } 69 | } 70 | 71 | export async function hardChain() { 72 | try { 73 | await ethereum.request({ 74 | method: 'wallet_switchEthereumChain', 75 | params: [{ chainId: '0x7A69' }], 76 | }); 77 | } catch (switchError) { 78 | if (switchError.code === 4902) { 79 | try { 80 | await window.ethereum.request({ 81 | method: 'wallet_addEthereumChain', 82 | params: [{ 83 | chainId: '0x7A69', 84 | chainName: 'HardHat', 85 | nativeCurrency: { 86 | name: 'ETH', 87 | symbol: 'ETH', 88 | decimals: 18, 89 | }, 90 | rpcUrls: ['http://node.a3b.io:8545'], 91 | blockExplorerUrls: [''], 92 | }] 93 | }) 94 | } catch (addError) { 95 | console.log('Error adding Chain'); 96 | } 97 | } 98 | } 99 | } 100 | 101 | export async function bscTest() { 102 | try { 103 | await ethereum.request({ 104 | method: 'wallet_switchEthereumChain', 105 | params: [{ chainId: '0x61' }], 106 | }); 107 | } catch (switchError) { 108 | if (switchError.code === 4902) { 109 | try { 110 | await window.ethereum.request({ 111 | method: 'wallet_addEthereumChain', 112 | params: [{ 113 | chainId: '0x61', 114 | chainName: 'BSC Testnet', 115 | nativeCurrency: { 116 | name: 'tBNB', 117 | symbol: 'tBNB', 118 | decimals: 18, 119 | }, 120 | rpcUrls: ['https://data-seed-prebsc-1-s3.binance.org:8545'], 121 | blockExplorerUrls: ['https://testnet.bscscan.com/'], 122 | }] 123 | }) 124 | } catch (addError) { 125 | console.log('Error adding Chain'); 126 | } 127 | } 128 | } 129 | } 130 | 131 | export async function ethTest() { 132 | try { 133 | await ethereum.request({ 134 | method: 'wallet_switchEthereumChain', 135 | params: [{ chainId: '0x5' }], 136 | }); 137 | } catch (switchError) { 138 | console.log('Wallet Not Connected') 139 | } 140 | } 141 | 142 | export async function polyTest() { 143 | try { 144 | await ethereum.request({ 145 | method: 'wallet_switchEthereumChain', 146 | params: [{ chainId: '0x13881' }], 147 | }); 148 | } catch (switchError) { 149 | if (switchError.code === 4902) { 150 | try { 151 | await window.ethereum.request({ 152 | method: 'wallet_addEthereumChain', 153 | params: [{ 154 | chainId: '0x13881', 155 | chainName: 'Polygon Mumbai', 156 | nativeCurrency: { 157 | name: 'MATIC', 158 | symbol: 'MATIC', 159 | decimals: 18, 160 | }, 161 | rpcUrls: ['https://matic-mumbai.chainstacklabs.com'], 162 | blockExplorerUrls: ['https://mumbai.polygonscan.com/'], 163 | }] 164 | }) 165 | } catch (addError) { 166 | console.log('Error adding Chain'); 167 | } 168 | } 169 | } 170 | } -------------------------------------------------------------------------------- /Part6-Final-Multichain-Integration/engine/configuration.js: -------------------------------------------------------------------------------- 1 | /* 2 | ___ ___ _ _ ___ _____ __ __ _ _ 3 | _ _ |_ )| \ | \| || __||_ _| | \/ | __ _ _ _ | |__ ___ | |_ 4 | | ' \ / / | |) | | .` || _| | | | |\/| |/ _` || '_|| / // -_)| _| 5 | |_||_|/___||___/ |_|\_||_| |_| |_| |_|\__,_||_| |_\_\\___| \__| 6 | 7 | Update values accordingly 8 | xxnft is the NFT Creator Contract Address 9 | xxmarket is the NFT MarketPlace Contract Address to sell created nfts. 10 | xxresell is the NFT MarketResell Contract Address for existing nfts. 11 | xxnftcol is the existing NFT Collection Address 12 | */ 13 | 14 | /* 15 | Private Key Encryption 16 | Replace ethraw with your private key "0xPRIVATEKEY" (Ethereum and other EVM) 17 | Replace hhraw with your private key "0xPRIVATEKEY" (Hardhat) 18 | */ 19 | import SimpleCrypto from "simple-crypto-js" 20 | const cipherKey = "#ffg3$dvcv4rtkljjkh38dfkhhjgt" 21 | const ethraw = "0x8207b7bbf486039b455923a402560ed041ad4b7243e9f329d6e415c00aaa9ef2"; 22 | const hhraw = "0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80"; 23 | export const simpleCrypto = new SimpleCrypto(cipherKey) 24 | export const cipherEth = simpleCrypto.encrypt(ethraw) 25 | export const cipherHH = simpleCrypto.encrypt(hhraw) 26 | 27 | /* 28 | IPFS API DETAILS 29 | */ 30 | import { create as ipfsHttpClient } from 'ipfs-http-client'; 31 | export const client = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0'); 32 | 33 | /* 34 | HardHat Testnet 35 | */ 36 | export var hhresell = "YOUR CONTRACT ADDRESS"; 37 | export var hhnftcol = "YOUR CONTRACT ADDRESS"; 38 | export var hhnft = "YOUR CONTRACT ADDRESS"; 39 | export var hhmarket = "YOUR CONTRACT ADDRESS"; 40 | export var hhrpc = "http://localhost:8545"; 41 | 42 | /* 43 | Goerli Testnet 44 | */ 45 | export var goeresell = "YOUR CONTRACT ADDRESS"; 46 | export var goenftcol = "YOUR CONTRACT ADDRESS"; 47 | export var goenft = "YOUR CONTRACT ADDRESS"; 48 | export var goemarket = "YOUR CONTRACT ADDRESS"; 49 | export var goerpc = "https://rpc.ankr.com/eth_goerli"; 50 | 51 | /* 52 | BSC Testnet 53 | */ 54 | export var bsctresell = "YOUR CONTRACT ADDRESS"; 55 | export var bsctnftcol = "YOUR CONTRACT ADDRESS"; 56 | export var bsctnft = "YOUR CONTRACT ADDRESS"; 57 | export var bsctmarket = "YOUR CONTRACT ADDRESS"; 58 | export var bsctrpc = "https://data-seed-prebsc-2-s3.binance.org:8545"; 59 | 60 | /* 61 | Mumbai Testnet 62 | */ 63 | export var mmresell = "YOUR CONTRACT ADDRESS"; 64 | export var mmnftcol = "YOUR CONTRACT ADDRESS"; 65 | export var mmnft = "YOUR CONTRACT ADDRESS"; 66 | export var mmmarket = "YOUR CONTRACT ADDRESS"; 67 | export var mmrpc = "https://matic-testnet-archive-rpc.bwarelabs.com"; 68 | -------------------------------------------------------------------------------- /Part6-Final-Multichain-Integration/engine/connectchain.js: -------------------------------------------------------------------------------- 1 | import { bscChain, polyChain, ethChain, hardChain, bscTest, ethTest, polyTest } from '../engine/chainchange'; 2 | import 'sf-font'; 3 | import { Col, Dropdown } from '@nextui-org/react'; 4 | import React from 'react'; 5 | import { useEffect } from 'react'; 6 | 7 | export default function ConnectChain() { 8 | const [selected, setSelected] = React.useState(new Set(["Set Network"])); 9 | const selectedValue = React.useMemo( 10 | () => Array.from(selected).join(", ").replaceAll("_", " "), 11 | [selected] 12 | ); 13 | 14 | const blockImage = React.useMemo(() => { 15 | var eth = "Ethereum"; 16 | var bsc = "Binance Smart Chain"; 17 | var pol = "Polygon"; 18 | var mum = "Mumbai"; 19 | var bsct = "Bsctest"; 20 | var goe = "Goerli"; 21 | var hard = "Hardhat"; 22 | var init = "Set Network"; 23 | if (selectedValue == eth) { 24 | return( 25 | 26 | ) 27 | } 28 | else if (selectedValue == bsc) { 29 | return( 30 | 31 | ) 32 | } 33 | else if (selectedValue == pol) { 34 | return( 35 | 36 | ) 37 | } 38 | else if (selectedValue == mum) { 39 | return( 40 |

Mumbai Testnet

41 | ) 42 | } 43 | else if (selectedValue == bsct) { 44 | return( 45 |

BSC Testnet

46 | ) 47 | } 48 | else if (selectedValue == goe) { 49 | return( 50 |

Goerli Testnet

51 | ) 52 | } 53 | else if (selectedValue == hard) { 54 | return( 55 |

Hardhat Node

56 | ) 57 | } 58 | else if (selectedValue == init) { 59 | return( 60 |
61 |

Select Network

62 |
63 | ) 64 | } 65 | }) 66 | 67 | async function enableChain() { 68 | var bsc = "Binance Smart Chain"; 69 | var poly = "Polygon"; 70 | var eth = "Ethereum"; 71 | var mum = "Mumbai"; 72 | var bsct = "Bsctest"; 73 | var goe = "Goerli"; 74 | var hard = "Hardhat"; 75 | if (bsc == selectedValue) { 76 | bscChain(); 77 | } else if (poly == selectedValue) { 78 | polyChain(); 79 | } else if (eth == selectedValue) { 80 | ethChain(); 81 | } else if (hard == selectedValue) { 82 | hardChain(); 83 | } else if (bsct == selectedValue) { 84 | bscTest(); 85 | } else if (goe == selectedValue) { 86 | ethTest(); 87 | } else if (mum == selectedValue) { 88 | polyTest(); 89 | } 90 | } 91 | useEffect(() => { 92 | enableChain(); 93 | }, [selected]); 94 | 95 | 96 | return ( 97 | 98 | 99 | 112 | {blockImage} 113 | 114 | 126 | 127 | 128 | 129 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | HardHat Node 140 | 141 | 142 | Goerli TestNet 143 | 144 | 145 | BSC TestNet 146 | 147 | 148 | Mumbai TestNet 149 | 150 | 151 | 152 | 153 | ); 154 | } -------------------------------------------------------------------------------- /Part6-Final-Multichain-Integration/pages/_app.js: -------------------------------------------------------------------------------- 1 | import { createTheme, NextUIProvider } from "@nextui-org/react"; 2 | import 'sf-font'; 3 | import Link from 'next/link' 4 | import { Button, Col, Row, Container } from '@nextui-org/react'; 5 | import Footer from './footer'; 6 | import Connectchain from "../engine/connectchain"; 7 | 8 | const theme = createTheme({ 9 | type: "dark", 10 | theme: { 11 | fontFamily:'SF Pro Display', 12 | colors: { 13 | primaryLight: '$blue200', 14 | primaryLightHover: '$blue300', 15 | primaryLightActive: '$blue400', 16 | primaryLightContrast: '$blue600', 17 | primary: '$purple500', 18 | primaryBorder: '$blue500', 19 | primaryBorderHover: '$blue600', 20 | primarySolidHover: '$blue700', 21 | primarySolidContrast: '$white', 22 | primaryShadow: '$white500', 23 | transparent: '#00000000', 24 | 25 | gradient: 'linear-gradient(112deg, $blue100 -25%, $pink500 -10%, $purple300 90%)', 26 | link: '#5E1DAD', 27 | 28 | myColor: '#00000030' 29 | 30 | }, 31 | space: {}, 32 | fonts: {} 33 | } 34 | }) 35 | 36 | function MyApp({ Component, pageProps }) { 37 | 38 | return( 39 |
40 |
41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 58 | 59 | 60 | 61 | 62 | 72 | 73 | 74 | 75 | 88 | 89 | 90 | 103 | 104 | < Connectchain /> 105 | 106 | 107 | 108 | 109 | 110 |
114 |
115 | 116 | ) 117 | 118 | 119 | } 120 | 121 | export default MyApp 122 | -------------------------------------------------------------------------------- /Part6-Final-Multichain-Integration/pages/create.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useState, useEffect } from 'react'; 3 | import { useRouter } from 'next/router'; 4 | import Web3Modal from "web3modal"; 5 | import NFT from '../engine/NFT.json'; 6 | import Market from '../engine/Market.json'; 7 | import { mmnft, mmmarket } from '../engine/configuration'; 8 | import { goenft, goemarket } from '../engine/configuration'; 9 | import { hhnft, hhmarket } from '../engine/configuration'; 10 | import { bsctnft, bsctmarket } from '../engine/configuration'; 11 | import detectEthereumProvider from '@metamask/detect-provider'; 12 | import { Card, Button, Input, Col, Row, Spacer, Container, Text } from '@nextui-org/react'; 13 | import { client } from '../engine/configuration'; 14 | import 'sf-font'; 15 | 16 | export default function createMarket() { 17 | const [fileUrl, setFileUrl] = useState(null) 18 | const [nftcontract, getNft] = useState([]) 19 | const [market, getMarket] = useState([]) 20 | 21 | const [formInput, updateFormInput] = useState({ price: '', name: '', description: '' }) 22 | 23 | useEffect(() => { 24 | setNft(); 25 | }, [getNft, getMarket]) 26 | 27 | const router = useRouter() 28 | 29 | async function onChange(e) { 30 | const file = e.target.files[0] 31 | try { 32 | const added = await client.add( 33 | file, 34 | { 35 | progress: (prog) => console.log(`received: ${prog}`) 36 | } 37 | ) 38 | const url = `https://ipfs.infura.io/ipfs/${added.path}` 39 | setFileUrl(url) 40 | } catch (error) { 41 | console.log('Error uploading file: ', error) 42 | } 43 | } 44 | 45 | async function createMarket() { 46 | const { name, description, price } = formInput 47 | if (!name || !description || !price || !fileUrl) return 48 | const data = JSON.stringify({ 49 | name, description, image: fileUrl 50 | }) 51 | try { 52 | const added = await client.add(data) 53 | const url = `https://ipfs.infura.io/ipfs/${added.path}` 54 | createNFT(url) 55 | } catch (error) { 56 | console.log('Error uploading file: ', error) 57 | } 58 | } 59 | 60 | async function setNft(){ 61 | const web3Modal = new Web3Modal() 62 | await web3Modal.connect(); 63 | var hh = "0x7a69"; 64 | var goe = "0x5"; 65 | var mm = "0x13881"; 66 | var bsct = "0x61"; 67 | const connected = await detectEthereumProvider(); 68 | if (connected.chainId == hh) { 69 | var nftcontract = hhnft 70 | } 71 | else if (connected.chainId == goe) { 72 | var nftcontract = goenft 73 | } 74 | else if (connected.chainId == mm) { 75 | var nftcontract = mmnft 76 | } 77 | else if (connected.chainId == bsct) { 78 | var nftcontract = bsctnft 79 | } 80 | getNft(nftcontract); 81 | console.log(nftcontract) 82 | setMarket(); 83 | } 84 | 85 | async function setMarket(){ 86 | var hh = "0x7a69"; 87 | var goe = "0x5"; 88 | var mm = "0x13881"; 89 | var bsct = "0x61"; 90 | const connected = await detectEthereumProvider(); 91 | if (connected.chainId == hh) { 92 | var market = hhmarket 93 | } 94 | else if (connected.chainId == goe) { 95 | var market = goemarket 96 | } 97 | else if (connected.chainId == mm) { 98 | var market = mmmarket 99 | } 100 | else if (connected.chainId == bsct) { 101 | var market = bsctmarket 102 | } 103 | getMarket(market); 104 | console.log(market) 105 | } 106 | 107 | async function createNFT(url) { 108 | const web3Modal = new Web3Modal() 109 | const connection = await web3Modal.connect() 110 | const provider = new ethers.providers.Web3Provider(connection) 111 | const signer = provider.getSigner() 112 | let contract = new ethers.Contract(nftcontract, NFT, signer) 113 | let transaction = await contract.createNFT(url) 114 | let tx = await transaction.wait() 115 | let event = tx.events[0] 116 | let value = event.args[2] 117 | let tokenId = value.toNumber() 118 | const price = ethers.utils.parseUnits(formInput.price, 'ether') 119 | contract = new ethers.Contract(market, Market, signer) 120 | let listingFee = await contract.listingFee() 121 | listingFee = listingFee.toString() 122 | transaction = await contract.createVaultItem(nftcontract, tokenId, price, { value: listingFee }) 123 | await transaction.wait() 124 | router.push('/') 125 | } 126 | 127 | async function buyNFT() { 128 | const { name, description } = formInput 129 | if (!name || !description || !fileUrl) return 130 | const data = JSON.stringify({ 131 | name, description, image: fileUrl 132 | }) 133 | try { 134 | const added = await client.add(data) 135 | const url = `https://ipfs.infura.io/ipfs/${added.path}` 136 | mintNFT(url) 137 | } catch (error) { 138 | console.log('Error uploading file: ', error) 139 | } 140 | } 141 | 142 | async function mintNFT(url) { 143 | const web3Modal = new Web3Modal() 144 | const connection = await web3Modal.connect() 145 | const provider = new ethers.providers.Web3Provider(connection) 146 | const signer = provider.getSigner() 147 | let contract = new ethers.Contract(nftcontract, NFT, signer) 148 | let cost = await contract.cost() 149 | let transaction = await contract.mintNFT(url, { value: cost }) 150 | await transaction.wait() 151 | router.push('/portal') 152 | } 153 | 154 | return ( 155 |
156 | 157 | 158 | NFT Creator Portal 159 | 160 | 161 | 162 | 163 | 164 | The NFT Marketplace with a Reward. 165 | N2DR IS More Than A Token 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | Select your Preferred Network, Create your Amazing NFT by uploading your art using the simple NFT Dashboard. Simple! 174 | 175 | 176 | 177 | 178 | 179 | Chain-Agnostic Marketplace that allows you to sell your NFT and accept your favorite crypto as payment! No borders, No restrictions. Simple! 180 | 181 | 182 | 183 | 184 | 185 | Create and Sell your NFT in the Marketplace 186 | 187 | 188 | 189 | updateFormInput({ ...formInput, name: e.target.value })} 192 | /> 193 | 194 | 195 | 196 | 197 | updateFormInput({ ...formInput, description: e.target.value })} 200 | /> 201 | 202 | 203 | 204 | 205 | 210 | { 211 | fileUrl && ( 212 | 213 | ) 214 | } 215 | 216 | 217 | 218 | updateFormInput({ ...formInput, price: e.target.value })} 222 | /> 223 | 226 | 229 | 230 | 231 | 232 | 233 | 234 |
235 | ) 236 | } 237 | -------------------------------------------------------------------------------- /Part6-Final-Multichain-Integration/pages/portal.js: -------------------------------------------------------------------------------- 1 | import { ethers } from 'ethers'; 2 | import { useState, useEffect } from 'react'; 3 | import Web3Modal from "web3modal"; 4 | import { useRouter } from 'next/router'; 5 | import Resell from '../engine/Resell.json'; 6 | import NFTCollection from '../engine/NFTCollection.json'; 7 | import NFT from '../engine/NFT.json'; 8 | import { polyTest, ethTest, bscTest } from '../engine/chainchange'; 9 | import { Card, Button, Input, Col, Row, Spacer, Container, Text, Grid } from '@nextui-org/react'; 10 | import axios from 'axios'; 11 | import 'sf-font'; 12 | import Web3 from 'web3'; 13 | import detectEthereumProvider from '@metamask/detect-provider'; 14 | import { mmnft, mmresell, mmnftcol, mmrpc } from '../engine/configuration'; 15 | import { goenft, goeresell, goenftcol, goerpc } from '../engine/configuration'; 16 | import { hhnft, hhresell, hhnftcol, hhrpc } from '../engine/configuration'; 17 | import { bsctnft, bsctresell, bsctnftcol, bsctrpc } from '../engine/configuration'; 18 | import { cipherEth, simpleCrypto } from '../engine/configuration'; 19 | 20 | export default function Sell() { 21 | const [user, getUser] = useState([]) 22 | const [chain, getChainName] = useState([]) 23 | const [rpc, getRpc] = useState([]) 24 | const [nftcol, getNftCol] = useState([]) 25 | const [nftcustom, getNftCustom] = useState([]) 26 | const [nftresell, getNftResell] = useState([]) 27 | const [created, getCreated] = useState([]) 28 | const [resalePrice, updateresalePrice] = useState({ price: ''}) 29 | const [nfts, setNfts] = useState([]) 30 | const [loadingState, setLoadingState] = useState('not-loaded') 31 | useEffect(() => { 32 | getChain(); 33 | setRpc(); 34 | }, [setNfts,getUser, getCreated]) 35 | const router = useRouter() 36 | 37 | async function setRpc(){ 38 | var hh = "0x7a69"; 39 | var goe = "0x5"; 40 | var mm = "0x13881"; 41 | var bsct = "0x61"; 42 | const connected = await detectEthereumProvider(); 43 | if (connected.chainId == hh) { 44 | var mainnet = hhrpc 45 | } 46 | else if (connected.chainId == goe) { 47 | var mainnet = goerpc 48 | } 49 | else if (connected.chainId == mm) { 50 | var mainnet = mmrpc 51 | } 52 | else if (connected.chainId == bsct) { 53 | var mainnet = bsctrpc 54 | } 55 | getRpc(mainnet); 56 | console.log(mainnet) 57 | setNftCol(); 58 | } 59 | 60 | async function setNftCol(){ 61 | var hh = "0x7a69"; 62 | var goe = "0x5"; 63 | var mm = "0x13881"; 64 | var bsct = "0x61"; 65 | const connected = await detectEthereumProvider(); 66 | if (connected.chainId == hh) { 67 | var nftcol = hhnftcol 68 | } 69 | else if (connected.chainId == goe) { 70 | var nftcol = goenftcol 71 | } 72 | else if (connected.chainId == mm) { 73 | var nftcol = mmnftcol 74 | } 75 | else if (connected.chainId == bsct) { 76 | var nftcol = bsctnftcol 77 | } 78 | getNftCol(nftcol); 79 | console.log(nftcol) 80 | setNftCustom(); 81 | } 82 | 83 | async function setNftCustom(){ 84 | var hh = "0x7a69"; 85 | var goe = "0x5"; 86 | var mm = "0x13881"; 87 | var bsct = "0x61"; 88 | const connected = await detectEthereumProvider(); 89 | if (connected.chainId == hh) { 90 | var nft = hhnft 91 | } 92 | else if (connected.chainId == goe) { 93 | var nft = goenft 94 | } 95 | else if (connected.chainId == mm) { 96 | var nft = mmnft 97 | } 98 | else if (connected.chainId == bsct) { 99 | var nft = bsctnft 100 | } 101 | getNftCustom(nft); 102 | console.log(nft) 103 | setNftResell(); 104 | } 105 | 106 | async function setNftResell(){ 107 | var hh = "0x7a69"; 108 | var goe = "0x5"; 109 | var mm = "0x13881"; 110 | var bsct = "0x61"; 111 | const connected = await detectEthereumProvider(); 112 | if (connected.chainId == hh) { 113 | var nftresell = hhresell 114 | } 115 | else if (connected.chainId == goe) { 116 | var nftresell = goeresell 117 | } 118 | else if (connected.chainId == mm) { 119 | var nftresell = mmresell 120 | } 121 | else if (connected.chainId == bsct) { 122 | var nftresell = bsctresell 123 | } 124 | getNftResell(nftresell); 125 | console.log(nftresell) 126 | } 127 | 128 | async function getChain(){ 129 | var hh = "0x7a69"; 130 | var goe = "0x5"; 131 | var mm = "0x13881"; 132 | var bsct = "0x61"; 133 | const connected = await detectEthereumProvider(); 134 | if (connected.chainId == hh) { 135 | var chainname = "HardHat" 136 | } 137 | else if (connected.chainId == goe) { 138 | var chainname = "Goerli Testnet" 139 | } 140 | else if (connected.chainId == mm) { 141 | var chainname = "Mumbai Testnet" 142 | } 143 | else if (connected.chainId == bsct) { 144 | var chainname = "BSC Testnet" 145 | } 146 | getChainName(chainname); 147 | console.log(chainname) 148 | } 149 | 150 | async function connectUser() { 151 | const web3Modal = new Web3Modal() 152 | const connection = await web3Modal.connect() 153 | const provider = new ethers.providers.Web3Provider(connection); 154 | const signer = provider.getSigner(); 155 | console.log(signer); 156 | if (window.ethereum) { 157 | var web3 = new Web3(window.ethereum); 158 | await window.ethereum.send("eth_requestAccounts"); 159 | var accounts = await web3.eth.getAccounts(); 160 | var account = accounts[0]; 161 | } 162 | getUser(account); 163 | } 164 | 165 | async function getWalletNFTs() { 166 | var address = nftcol 167 | var network = rpc 168 | console.log(address) 169 | const provider = new ethers.providers.JsonRpcProvider(network) 170 | const key = simpleCrypto.decrypt(cipherEth) 171 | const wallet = new ethers.Wallet(key, provider); 172 | const contract = new ethers.Contract(address, NFTCollection, wallet) 173 | const itemArray = []; 174 | contract.totalSupply().then(result => { 175 | for (let i = 0; i < result; i++) { 176 | var token = i + 1 177 | const owner = contract.ownerOf(token).catch(function (error) { 178 | console.log("tokens filtered"); 179 | }); 180 | const rawUri = contract.tokenURI(token).catch(function (error) { 181 | console.log("tokens filtered"); 182 | }); 183 | const Uri = Promise.resolve(rawUri) 184 | const getUri = Uri.then(value => { 185 | var cleanUri = value.replace('ipfs://', 'https://ipfs.io/ipfs/') 186 | let metadata = axios.get(cleanUri).catch(function (error) { 187 | console.log(error.toJSON()); 188 | }); 189 | return metadata; 190 | }) 191 | getUri.then(value => { 192 | let rawImg = value.data.image 193 | var name = value.data.name 194 | var desc = value.data.description 195 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 196 | Promise.resolve(owner).then(value => { 197 | let ownerW = value; 198 | let meta = { 199 | name: name, 200 | img: image, 201 | tokenId: token, 202 | wallet: ownerW, 203 | desc, 204 | } 205 | console.log(meta) 206 | itemArray.push(meta) 207 | }) 208 | }) 209 | } 210 | }) 211 | await new Promise(r => setTimeout(r, 2000)); 212 | setNfts(itemArray) 213 | setLoadingState('loaded'); 214 | } 215 | 216 | 217 | async function getCreatedNFTs() { 218 | var address = nftcustom 219 | var network = rpc 220 | const provider = new ethers.providers.JsonRpcProvider(network) 221 | const key = simpleCrypto.decrypt(cipherEth) 222 | const wallet = new ethers.Wallet(key, provider); 223 | const contract = new ethers.Contract(address, NFT, wallet) 224 | const itemArray = []; 225 | contract._tokenIds().then(result => { 226 | for (let i = 0; i < result; i++) { 227 | var token = i + 1 228 | const owner = contract.ownerOf(token).catch(function (error) { 229 | console.log("tokens filtered"); 230 | }); 231 | const rawUri = contract.tokenURI(token).catch(function (error) { 232 | console.log("tokens filtered"); 233 | }); 234 | const Uri = Promise.resolve(rawUri) 235 | const getUri = Uri.then(value => { 236 | var cleanUri = value.replace('ipfs://', 'https://ipfs.io/ipfs/') 237 | let metadata = axios.get(cleanUri).catch(function (error) { 238 | console.log(error.toJSON()); 239 | }); 240 | return metadata; 241 | }) 242 | getUri.then(value => { 243 | let rawImg = value.data.image 244 | var name = value.data.name 245 | var desc = value.data.description 246 | let image = rawImg.replace('ipfs://', 'https://ipfs.io/ipfs/') 247 | Promise.resolve(owner).then(value => { 248 | let ownerW = value; 249 | let meta = { 250 | name: name, 251 | img: image, 252 | tokenId: token, 253 | wallet: ownerW, 254 | desc, 255 | } 256 | console.log(meta) 257 | itemArray.push(meta) 258 | }) 259 | }) 260 | } 261 | }) 262 | await new Promise(r => setTimeout(r, 2000)); 263 | getCreated(itemArray) 264 | setLoadingState('loaded'); 265 | } 266 | 267 | async function refreshNFTs(){ 268 | connectUser(); 269 | setRpc(); 270 | getCreatedNFTs(); 271 | getWalletNFTs(); 272 | getChain(); 273 | } 274 | 275 | async function connectWallet(){ 276 | connectUser(); 277 | setRpc(); 278 | getChain(); 279 | } 280 | 281 | 282 | 283 | if (loadingState === 'loaded' && !nfts.length) 284 | return ( 285 | 286 | 287 | 288 | No NFT's Found, Connect Wallet 289 | 297 | 298 | 299 | 300 | 301 | ) 302 | return ( 303 |
304 | 305 | 306 | 307 | 308 | 309 | 310 | Switch Blockchain 311 | 312 | 315 | 318 | 321 | 322 | 323 | 324 | Wallet 325 | 326 | {user} 327 | 328 | 329 | Selected Chain: {chain} 330 | 331 | 339 | 347 | 348 | 349 | 350 | 351 | 352 | 353 | 354 | {nfts.map((nft, i) => { 355 | var owner = user; 356 | if (owner.indexOf(nft.wallet) !== -1) { 357 | async function executeRelist() { 358 | const { price } = resalePrice; 359 | if (!price) return; 360 | try { 361 | relistNFT(); 362 | } catch (error) { 363 | console.log("Transaction Failed", error); 364 | } 365 | } 366 | async function relistNFT() { 367 | var resell = nftresell 368 | const web3Modal = new Web3Modal(); 369 | const connection = await web3Modal.connect(); 370 | const provider = new ethers.providers.Web3Provider(connection); 371 | const signer = provider.getSigner(); 372 | const price = ethers.utils.parseUnits( 373 | resalePrice.price, 374 | "ether" 375 | ); 376 | const contractnft = new ethers.Contract( 377 | nftcol, 378 | NFTCollection, 379 | signer 380 | ); 381 | await contractnft.setApprovalForAll(resell, true); 382 | let contract = new ethers.Contract(resell, Resell, signer); 383 | let listingFee = await contract.getListingFee(); 384 | listingFee = listingFee.toString(); 385 | let transaction = await contract.listSale(nft.tokenId, price, { 386 | value: listingFee, 387 | }); 388 | await transaction.wait(); 389 | router.push("/"); 390 | } 391 | return ( 392 | 393 | 394 | 400 | 401 | 402 |

408 | Owned by You 409 |

410 | 411 | {nft.name} Token-{nft.tokenId} 412 | 413 | {nft.desc} 414 | 430 | updateresalePrice({ 431 | ...resalePrice, 432 | price: e.target.value, 433 | }) 434 | } 435 | /> 436 | 444 |
445 |
446 |
447 |
448 | ); 449 | } 450 | })} 451 |
452 |
453 |
454 | 455 | 456 | Personal NFTs 457 | 458 | 459 | {created.map((nft, i) => { 460 | var owner = user; 461 | if (owner.indexOf(nft.wallet) !== -1) { 462 | return ( 463 | 464 | 465 | 471 | 472 | 473 |

479 | Owned by You 480 |

481 | 482 | {nft.name} Token-{nft.tokenId} 483 | 484 | {nft.desc} 485 |
486 |
487 |
488 |
489 | ); 490 | } 491 | })} 492 |
493 |
494 |
495 |
496 | ) 497 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

Multi-Chain NFT Marketplace

3 | ## 4 | 🚀👩‍🚀This repo contains all the files to follow along and implement a MultiChain NFT MarketPlace! Be sure to watch my Youtube tutorials so you can learn and follow along! 5 | 6 | ** THE FILES ATTACHED TO THIS REPO ARE FOR EDUCATIONAL PURPOSES ONLY ** 7 | 8 | ** NOT FINANCIAL ADVISE ** 9 | 10 | ** USE IT AT YOUR OWN RISK** **I'M NOT RESPONSIBLE FOR ANY USE, ISSUES ETC.. ** 11 | 12 | Please follow instructions for the video tutorial you are watching. 13 | 14 | ## Part-1 Hardhat and EthersJS 15 | 16 | Click for video: 17 | 18 | 19 | 20 | Steps: 21 | 22 | 1-Create an new NextJS app: 23 | 24 | ```shell 25 | npx create-next-app n2dmarket 26 | ``` 27 | 28 | 2- Install hardhat in the n2dmarket project folder. 29 | 30 | ```shell 31 | npm i hardhat 32 | ``` 33 | 34 | 3- Create a hardhat environment. 35 | 36 | ```shell 37 | npx hardhat 38 | ``` 39 | 40 | 4- Refer to the Hardhat and EthersJS knowledge base and 41 | practice some info gathering using the hardhat console: 42 | 43 | ```shell 44 | npx hardhat console 45 | ``` 46 | 47 | Hardhat Knowledge Base : https://hardhat.org/tutorial 48 | 49 | EthersJS Knowledge Base: https://docs.ethers.io/v5/ 50 | 51 | ## Part-2 NFT Market Resell Smart Contract 52 | 53 | Click for video: 54 | 55 | 56 | 57 | 58 | 1-Retrieve the NFT Collection Smart Contract Address. 59 | 60 | 2-Deploy the NFT Market Resell Smart Contract located in Part2 Folder. 61 | 62 | Add the NFT Collection Address when deploying the smart contract. 63 | 64 | ## Part-3 Deploy a NextJS WebFront End 65 | 66 | Click for video: 67 | 68 | 69 | 70 | Steps: 71 | 72 | 1- Navigate to your n2dmarket project folder and install the remaining dependencies: 73 | 74 | ```shell 75 | npm i --save-dev "@types/react" 76 | 77 | npm i axios @nextui-org/react sf-font 78 | 79 | npm i simple-crypto-js web3modal 80 | 81 | npm i @metamask/detect-provider 82 | 83 | npm i ipfs-http-client 84 | 85 | npm i web3 86 | 87 | npm i --save-dev @types/canvas-confetti 88 | ``` 89 | 90 | 2- Proceed to replace the files in your n2dmarket folder with each respective 91 | 92 | file attached in the Part-3 Folder, Add the "engine" folder to the project root folder. 93 | 94 | 95 | 3- Deploy your test NFT Collection and NFT Market Resell Smart Contracts (refer to Part2 Vid) 96 | 97 | and go to /engine/configuration and update the values accordingly: 98 | 99 | ```shell 100 | 101 | export var hhresell = "YOUR NFT RESELL MARKET SMART CONTRACT"; 102 | 103 | export var hhnftcol = "YOUR NFT COLLECTION SMART CONTRACT"; 104 | 105 | var hhrpc = "YOUR MAINNET OR TESTNET RPC ADDRESS"; 106 | ``` 107 | 108 | List of RPC Address to use depending on which testnet the contracts have been deployed: 109 | 110 | Polygon Mumbai: https://matic-mumbai.chainstacklabs.com 111 | 112 | BSC Testnet: https://data-seed-prebsc-1-s3.binance.org:8545 113 | 114 | ETH Goerli: https://rpc.ankr.com/eth_goerli 115 | 116 | CTRL + S to save configs 117 | 118 | Run the web server and validate: 119 | 120 | ```shell 121 | npm run dev 122 | ``` 123 | 124 | Watch part 3 vid for more details. 125 | 126 | ## Part-4 Relist and Buy NFTs! 127 | 128 | Click for video: 129 | 130 | 131 | 132 | Steps: 133 | 134 | 1- New changes have been performed on the Resell SmartContract. 135 | Redeploy it on your favorite testnet and save the address. 136 | 137 | Contract link: 138 | 139 | https://github.com/net2devcrypto/N2D-NFT-Marketplace/tree/main/Part2-NFT-Market-Resell-Contract 140 | 141 | 2- Install NFT Carousel Dependency: 142 | 143 | ```shell 144 | npm i --save-dev react-multi-carousel 145 | ``` 146 | 147 | 3- Proceed to replace the files in your market project folder with each respective 148 | 149 | file attached in the Part-4 Folder, Replace "engine" and "public" folder with all files as well. 150 | 151 | 152 | 4- Obtain your Resell Smart Contract Owner Wallet Private Key. (Wallet used to deploy contract) 153 | 154 | Go to /engine/configuration and update the values accordingly: 155 | 156 | Replace with your Private key in "hhraw": 157 | 158 | ```shell 159 | const hhraw = "0xREPLACEWITHPRIVATEKEY"; 160 | ``` 161 | 162 | Add your smart contract addresses here: 163 | 164 | ```shell 165 | export var hhresell = "YOUR NFT RESELL MARKET SMART CONTRACT"; 166 | 167 | export var hhnftcol = "YOUR NFT COLLECTION SMART CONTRACT"; 168 | 169 | var hhrpc = "REPLACE WITH THE TESTNET RPC"; 170 | ``` 171 | 172 | CTRL + S to save configs 173 | 174 | Run the web server and validate: 175 | 176 | ```shell 177 | npm run dev 178 | ``` 179 | Watch part 4 vid for more details. 180 | 181 | ## Part-5 Create The NFT Marketplace Contract and App to upload Art and mint NFTs. 182 | 183 | Click for video: 184 | 185 | 186 | 187 | 188 | 1-Deploy the Marketplace Contract to sell created NFTs located in Part5 Folder repo. Copy the contract address. 189 | 190 | https://github.com/net2devcrypto/N2D-NFT-Marketplace/blob/main/Part5-Create-and-Sell-NFT-App/N2D-Market-SellCreatedNFT-SmartContract.sol 191 | 192 | 2-Deploy the NFT Smart Contract to create NFTs located in Part5 Folder, add the NFT Market smart contract to sell created NFTs when deploying and copy the contract address once deployed. 193 | 194 | https://github.com/net2devcrypto/N2D-NFT-Marketplace/blob/main/Part5-Create-and-Sell-NFT-App/N2D-Market-CreateNFT-SmartContract.sol 195 | 196 | 3- Go to /engine/configuration and add the additional contracts accordingly: 197 | 198 | ```shell 199 | 200 | export var hhnft = "YOUR CREATE NFT SMART CONTRACT"; 201 | 202 | export var hhmarket = "YOUR SELL CREATED NFT MARKETPLACE SMART CONTRACT"; 203 | 204 | ``` 205 | 206 | 4- From Part5 Folder, Proceed to add the NFT and Market ABI files to the engine folder. Proceed to replace the files in your project with the ones provided in the Part5 folder. Test and practice. Time to learn more! 207 | 208 | Watch Part 5 video for more info. 209 | 210 | ## Part-6 Final Video - Enable Multichain Integration! 211 | 212 | Click for video: 213 | 214 | 215 | 216 | 217 | 1- Stop NextJS Server and Replace all files in your project with the files attached on this repo to their respective folders. 218 | 219 | 2-Deploy all required smart contracts for all networks and update the contract address in the configuration.js file located in the "engine" folder. 220 | 221 | Deploy the contracts on all required testnets. The "nftcol" is an existing nft collection smartcontract. 222 | 223 | resell smartcontract : https://github.com/net2devcrypto/N2D-NFT-Marketplace/blob/main/Part2-NFT-Market-Resell-Contract/N2D-Market-NFT-Resell-SmartContract.sol 224 | 225 | nft smartcontract: https://github.com/net2devcrypto/N2D-NFT-Marketplace/blob/main/Part5-Create-and-Sell-NFT-App/N2D-Market-CreateNFT-SmartContract.sol 226 | 227 | market smartcontract: https://github.com/net2devcrypto/N2D-NFT-Marketplace/blob/main/Part5-Create-and-Sell-NFT-App/N2D-Market-SellCreatedNFT-SmartContract.sol 228 | 229 | Example for Goerli Testnet 230 | 231 | ```shell 232 | export var goeresell = "YOUR CONTRACT ADDRESS"; 233 | export var goenftcol = "YOUR CONTRACT ADDRESS"; 234 | export var goenft = "YOUR CONTRACT ADDRESS"; 235 | export var goemarket = "YOUR CONTRACT ADDRESS"; 236 | ``` 237 | 238 | Save your changes! 239 | 240 | 3- Install Metamask detect provider dependency in your project folder. 241 | 242 | ```shell 243 | npm i @metamask/detect-provider 244 | ``` 245 | 246 | 4- Start NextJS server and follow the video for additional testing and practice steps. 247 | 248 | 249 | -------------------------------------------------------------------------------- /n2DMarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/net2devcrypto/N2D-NFT-Marketplace/a8d9ada82ef143eb3df282c3d0c7f4cf0b5bf6af/n2DMarket.png --------------------------------------------------------------------------------