Skip to content

Commit

Permalink
Mint contract logic change
Browse files Browse the repository at this point in the history
  • Loading branch information
spandan114 committed Mar 13, 2022
1 parent bff796e commit 39589a3
Show file tree
Hide file tree
Showing 10 changed files with 162 additions and 86 deletions.
11 changes: 4 additions & 7 deletions contracts/NFT.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,15 @@ import "@openzeppelin/contracts/utils/Counters.sol";
contract NFT is ERC721URIStorage {
using Counters for Counters.Counter;
Counters.Counter private _tokenIdCounter;
address public marketPlaceContractAddress;

constructor(address marketPlaceAddress) ERC721("Exchange NFT", "EXNFT") {
marketPlaceContractAddress = marketPlaceAddress;
}
constructor() ERC721("Exchange NFT", "EXNFT") {}

function safeMint(string memory uri) public payable returns(uint) {
function safeMint(string memory uri,address marketPlaceAddress,address creator) public payable returns(uint) {
_tokenIdCounter.increment();
uint256 tokenId = _tokenIdCounter.current();
_mint(msg.sender, tokenId);
_mint(creator, tokenId);
_setTokenURI(tokenId, uri);
setApprovalForAll(marketPlaceContractAddress,true);
_setApprovalForAll(creator,marketPlaceAddress,true);
return tokenId;
}

Expand Down
10 changes: 6 additions & 4 deletions contracts/NFTMarket.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import "hardhat/console.sol";
import "@openzeppelin/contracts/utils/Counters.sol";
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";

import "./NFT.sol";
// [X] Create & List Nft
// [X] Buy NFT
// [X] Sell NFT
Expand Down Expand Up @@ -60,17 +60,19 @@ contract NFTMarket is ReentrancyGuard{

mapping(uint => _Item) public Items;

function sellItem(uint256 _tokenId,uint256 _price,address _nftContract) payable public nonReentrant{
function sellItem(string memory uri,uint256 _price,address _nftContract) payable public nonReentrant{
require(_price > 0, "Price must be at least 1 wei");
require(msg.value == mintingCost, "Price must be equal to listing price");

_itemId.increment();
uint256 itemId = _itemId.current();

uint256 _tokenId = NFT(_nftContract).safeMint(uri,address(this),msg.sender);

Items[itemId] = _Item(
ListingStatus.Active,
_nftContract,
payable(address(0)),
payable(address(this)),
payable(msg.sender),
_tokenId,
_price
Expand All @@ -80,7 +82,7 @@ contract NFTMarket is ReentrancyGuard{

emit Item(
_nftContract,
payable(address(0)),
payable(address(this)),
payable(msg.sender),
_tokenId,
_price
Expand Down
13 changes: 13 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"react": "17.0.2",
"react-dom": "17.0.2",
"react-redux": "^7.2.6",
"react-toastify": "^8.2.0",
"redux": "^4.1.2",
"redux-thunk": "^2.4.1"
},
Expand Down
20 changes: 19 additions & 1 deletion pages/_app.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,26 @@
import '../styles/globals.css'
import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import {wrapper} from '../redux/store'
import { loadAccount, loadContracts, loadWeb3 } from "../redux/interactions";
import { useDispatch } from 'react-redux';
import { useEffect } from 'react';

function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />

const dispatch = useDispatch()

useEffect(() => {
loadBlockchain()
}, [])

const loadBlockchain = async()=>{
const provider = await loadWeb3(dispatch)
await loadContracts(provider,dispatch)
await loadAccount(provider,dispatch)
}

return <><ToastContainer /><Component {...pageProps} /></>
}

export default wrapper.withRedux(MyApp)
15 changes: 0 additions & 15 deletions pages/index.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,10 @@
import Head from "next/head";
import Image from "next/image";
import { useEffect } from "react";
import { useDispatch } from "react-redux";
import CardComponent from "../components/Card";
import { basicAuth } from "../helpers/AuthHelper";
import { loadAccount, loadContracts, loadWeb3 } from "../redux/interactions";

const Home = () => {

const dispatch = useDispatch()

useEffect(() => {
loadBlockchain()
}, [])

const loadBlockchain = async()=>{
const provider = await loadWeb3(dispatch)
await loadContracts(provider,dispatch)
await loadAccount(provider,dispatch)
}

return (
<div className="container home">
<Head>
Expand Down
115 changes: 90 additions & 25 deletions pages/mint.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
import React, { useState } from "react";
import React, { useRef, useState } from "react";
import { basicAuth } from "../helpers/AuthHelper";
import { toast } from 'react-toastify';
import { create } from "ipfs-http-client";
import { useSelector } from "react-redux";
const client = create("https://ipfs.infura.io:5001/api/v0");

const Mint = () => {
const formRef = useRef(null);
const [file, setFile] = useState("");
const [name, setName] = useState("");
const [price, setPrice] = useState("");
const [description, setDescription] = useState("");
const [attributes, setAttributes] = useState(null);
const [fileUrl, setFileUrl] = useState("");
const [loader, setLoader] = useState(false);

const web3Provider = useSelector(state=>state.web3Reducer.connection)
const walletAddress = useSelector(state=>state.web3Reducer.account)
const nftReducer = useSelector(state=>state.nftReducer.contract)
const nftMarketplaceReducer = useSelector(state=>state.nftMarketplaceReducer.contract)

const addAttribute = (e) => {
e.preventDefault();
Expand All @@ -22,52 +31,104 @@ const Mint = () => {
value: e.target.value.value,
},
];
setAttributes(attr);
console.log(attr);
setAttributes(attr)
} else {
setAttributes([
{ id: 0, trait_type: e.target.key.value, value: e.target.value.value },
]);
}
formRef.current.reset();
};

const removeAttribute = (id) => {
var filteredAttr = attributes.filter((data) => data.id !== id);
setAttributes(filteredAttr);
};

async function uploadImageToIPFS(e) {
e.preventDefault();
const uploadImageToIPFS = async()=> {
setLoader(true)
if (!name || !description || !price || !file) {
toast.error("Please fill all the required fields !", {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
};

console.log(file);
// try {
// const added = await client.add(file)
// const url = `https://ipfs.infura.io/ipfs/${added.path}`
// await uploadMetadataToIPFS(url)
// } catch (error) {
// console.log('Error uploading file: ', error)
// }
try {
const added = await client.add(file)
const url = `https://ipfs.infura.io/ipfs/${added.path}`
await uploadMetadataToIPFS(url)
} catch (error) {
setLoader(false)
toast.error("Image upload failed !", {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
console.log('Error uploading file: ', error)
}
}

async function uploadMetadataToIPFS(name, description, attributes, fileUrl) {
const uploadMetadataToIPFS = async(fileUrl) => {
if (!name || !description || !price || !fileUrl) return;
/* first, upload to IPFS */
const data = JSON.stringify({
name: name,
description: description,
attributes: attributes,
image: fileUrl,
attributes: attributes
});
try {
const added = await client.add(data);
const url = `https://ipfs.infura.io/ipfs/${added.path}`;
/* after file is uploaded to IPFS, return the URL to use it in the transaction */
await mintNFT(url)

return url;
} catch (error) {
setLoader(false)
toast.error("Meta data upload failed !", {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
console.log("Error uploading file: ", error);
}
}

const mintNFT = async(metadata) =>{
try {
const tx = await nftReducer.safeMint(metadata,{from:walletAddress})
const receipt = await tx.wait();
console.log(receipt)
setLoader(false)
} catch (error) {
toast.error(error.message, {
position: "top-right",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});

}
}

return (
<div className="container create-nft">
<div className="card m-5 p-4">
Expand Down Expand Up @@ -121,40 +182,44 @@ const Mint = () => {
></textarea>
</div>

<form onSubmit={(e) => addAttribute(e)}>
<form onSubmit={(e) => addAttribute(e)} ref={formRef}>
<div className="mb-3">
<label htmlFor="attributes" className="form-label">
Attributes
</label>

<div className="d-flex flex-wrap">
{
attributes?
attributes.map((attr,i)=>(
<p key={i}>{attr.trait_type}</p>
))
:""
}

attributes?
attributes.map((attr,i)=>{
return (
<span key={i} className="m-1 badge attr-badge" onClick={()=>removeAttribute(attr.id)}>{attr.trait_type}:{attr.value}</span>
)
})
:""
}
</div>
<div className="d-flex attribute">
<input
type="text"
name="key"
className="form-control m-1"
placeholder="Key"
required
/>
<input
type="text"
name="value"
className="form-control m-1"
placeholder="Value"
required
/>
<button type="submit" className="btn btn-primary mb-2 btn-sm">
Add
</button>
</div>
</div>
</form>
<button type="submit" className="btn btn-success btn-block">
<button type="submit" className="btn btn-success btn-block" onClick={()=>mintNFT("abcd.com")}>
Mint NFT
</button>
</div>
Expand Down
6 changes: 3 additions & 3 deletions redux/interactions.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ const weiToEther = (num) =>{
}

export const loadContracts = async(provider,dispatch) =>{

const nftMarketplaceContract = new ethers.Contract(marketPlaceAddress, NFTMarketContract.abi, provider);
const nftContract = new ethers.Contract(nftAddress, NFTContract.abi, provider);
const signer = provider.getSigner();
const nftMarketplaceContract = new ethers.Contract(marketPlaceAddress, NFTMarketContract.abi, signer);
const nftContract = new ethers.Contract(nftAddress, NFTContract.abi, signer);

dispatch(actions.nftMarketplaceContractLoaded(nftMarketplaceContract))
dispatch(actions.nftContractLoaded(nftContract))
Expand Down
4 changes: 4 additions & 0 deletions styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,4 +97,8 @@ a {

.attribute button{
width: 30% !important;
}

.attr-badge{
background: var(--light-black-s);
}
Loading

0 comments on commit 39589a3

Please sign in to comment.