I am creating a solidity based Dapp for nft marketplace. so i have to link my smart contracts with ipfs in order to upload resources as tokens. but everytime i try to upload i am getting this error: https://ipfs.infura.io:5001/api/v0/add?stream-channels=true&progress=false 401 (Unauthorized)
also the error message is: Error uploading file: HTTPError: project id required
at Object.errorHandler [as handleError] (core.js?7300:104:1)
at async Client.fetch (http.js?8f3e:161:1)
at async addAll (add-all.js?7d92:36:1)
at async last (index.js?7351:7:1)
at async Object.add (add.js?fa1f:22:1)
at async onChange (mint-item.js?8cc6:33:23)
after infura update, public gateways are no longer in use and hence, we have to create and use dedicated gateways. i've also created one. also, infura now requires your ipfs projectid and secretkey in the smart contract you've created. despite making all those changes in my code as previously it used to be, the problem still exists. and the projectid isn't readable(as in the error message.)
please recommend anymore changes that are required in my code below:
import {ethers} from 'ethers'
import {useState} from 'react'
import Web3Modal from 'web3modal'
import { create as ipfsHttpClient } from 'ipfs-http-client'
import { Buffer } from 'buffer'
import { nftaddress, nftmarketaddress } from '../config'
import NFT from '../artifacts/contracts/NFT.sol/NFT.json'
import {useRouter} from 'next/router'
import KBMarket from '../artifacts/contracts/KBMarket.sol/KBMarket.json'
// in this component we set the ipfs up to host our nft data of
// file storage
const client = ipfsHttpClient('https://ipfs.infura.io:5001') //IPFS API ENDPOINT
const projectId = "<project_Id>"
const projectSecret = "<project_Secret>"
const auth =
'Basic ' + Buffer.from(projectId + ':' + projectSecret).toString('base64');
export default function MintItem() {
const [fileUrl, setFileUrl] = useState(null)
const [formInput, updateFormInput] = useState({price: '', name:'',
description:''})
const router = useRouter()
// set up a function to fireoff when we update files in our form - we can add our
// NFT images - IPFS
async function onChange(e) {
const file = e.target.files[0]
try {
const added = await client.add(
file, {
progress: (prog) => console.log(`received: ${prog}`)
})
const url = `https://nextnftpolygon.infura-ipfs.io/ipfs/${result.path}`
setFileUrl(url)
} catch (error) {
console.log('Error uploading file:', error)
}
}
async function createMarket() {
const {name, description, price} = formInput
if(!name || !description || !price || !fileUrl) return
// upload to IPFS
const data = JSON.stringify({
name, description, image: fileUrl
})
try {
const added = await client.add(data)
const url = `https://nextnftpolygon.infura-ipfs.io/ipfs/${result.path}`
// run a function that creates sale and passes in the url
createSale(url)
} catch (error) {
console.log('Error uploading file:', error)
}
}
async function createSale(url) {
// create the items and list them on the marketplace
const web3Modal = new Web3Modal()
const connection = await web3Modal.connect()
const provider = new ethers.providers.Web3Provider(connection)
const signer = provider.getSigner()
// we want to create the token
let contract = new ethers.Contract(nftaddress, NFT.abi, signer)
let transaction = await contract.mintToken(url)
let tx = await transaction.wait()
let event = tx.events[0]
let value = event.args[2]
let tokenId = value.toNumber()
const price = ethers.utils.parseUnits(formInput.price, 'ether')
// list the item for sale on the marketplace
contract = new ethers.Contract(nftmarketaddress, KBMarket.abi, signer)
let listingPrice = await contract.getListingPrice()
listingPrice = listingPrice.toString()
transaction = await contract.makeMarketItem(nftaddress, tokenId, price, {value: listingPrice})
await transaction.wait()
router.push('./')
}
return (
<div className='flex justify-center'>
<div className='w-1/2 flex flex-col pb-12'>
<input
placeholder='Asset Name'
className='mt-8 border rounded p-4'
onChange={ e => updateFormInput({...formInput, name: e.target.value})}
/>
<textarea
placeholder='Asset Description'
className='mt-2 border rounded p-4'
onChange={ e => updateFormInput({...formInput, description: e.target.value})}
/>
<input
placeholder='Asset Value (ETH)'
className='mt-2 border rounded p-4'
onChange={ e => updateFormInput({...formInput, price: e.target.value})}
/>
<input
type='file'
name='Asset'
className='mt-4'
onChange={onChange}
/> {
fileUrl && (
<img className='rounded mt-4' width='350px' src={fileUrl} />
)}
<button
onClick={createMarket}
className='font-bold mt-4 bg-purple-500 text-white rounded p-4 shadow-lg'
>
Mint Token
</button>
</div>
</div>
)
}