I am currently building an NFT-related app and currently trying to mint the NFT using a test network. I am trying to upload the image file to ipfs.
To upload an image, I am currently using a dropzone to get the file:
const client = ipfsHttpClient('https://ipfs.infura.io:5001/api/v0');
const CreateItem = () => {
const uploadToInfura = async (file) => {
try {
const added = await client.add({ content: file });
const url = `https://ipfs.infura.io/ipfs/${added.path}`;
setFileUrl(url);
} catch (error) {
console.log('Error uploading file: ', error);
}
};
const onDrop = useCallback(async (acceptedFile) => {
await uploadToInfura(acceptedFile[0]);
}, []);
const {
getRootProps,
getInputProps,
isDragActive,
isDragAccept,
isDragReject,
} = useDropzone({
onDrop,
accept: 'image/*',
maxSize: 5000000,
});
const fileStyle = useMemo(
() => `dark:bg-nft-black-1 bg-white border dark:border-white border-nft-gray-2 flex flex-col items-center p-5 rounded-sm border-dashed
${isDragActive ? ' border-file-active ' : ''}
${isDragAccept ? ' border-file-accept ' : ''}
${isDragReject ? ' border-file-reject ' : ''}`,
[isDragActive, isDragReject, isDragAccept],
);
return (
<div className="flex justify-center sm:px-4 p-12">
<div className="w-3/5 md:w-full">
<h1 className="font-grotesque text-white text-2xl">
Create new item
</h1>
<div className="mt-16">
<p className="font-grotesque dark:text-white text-nft-black-1 text-xl">
Upload file
</p>
<div className="mt-4">
<div {...getRootProps()} className={fileStyle}>
<input {...getInputProps()} />
<div className="flexCenter flex-col text-center">
<p className="font-grotesk dark:text-white text-nft-black-1 text-xl">
JPG, PNG, GIF, SVG, WEBM, MP3, MP4. Max 100mb.
</p>
<p className="font-poppins dark:text-white text-nft-black-1 font-grotesk text-sm">
Drag and Drop File
</p>
</div>
</div>
</div>
</div>
</div>
</div>
);
};
export default CreateItem;
Above is a simplified version of my component. I am attempting to pass the file as a prop to my own upload to infura method.
The program was working fine however when attempting to use the platform today I kept running into the same error.
Whenever an attempt to upload was made the POST request fails. This is the error logged:
ipfs.infura.io:5001/api/v0/add?stream-channels=true&progress=false:1 Failed to load resource: the server responded with a status of 401 (Unauthorized)
fetch.browser.js?c17b:106 POST https://ipfs.infura.io:5001/api/v0/add?stream-channels=true&progress=false 401 (Unauthorized)
I am connected to wifi and within the file size limit. Is anyone familiar with this error?
CodePudding user response:
I think you have to pass the authorization header when you make request to infura. before it was easy to use infura but now they even require credit card to hold on to the account.
The Infura IPFS public gateway was deprecated on August 10, 2022
You probably get this error, too "HTTPError: project id required"
const ipfsClient = require(‘ipfs-http-client’);
const projectId = ’XXX...XXX;
const projectSecret = ‘XXX...XXX’;
const auth = ‘Basic ’ Buffer.from(projectId ‘:’ projectSecret).toString(‘base64’);
const client = ipfsClient.create({
host: ‘ipfs.infura.io’,
port: 5001,
protocol: ‘https’,
headers: {
authorization: auth,
},
});
Read this to enable a dedicated gateway: ipfs-public-api-and-gateway-deprecation
You can now access a dedicated gateway to decentralized storage for your projects through the Infura IPFS API. A gateway allows applications, such as browsers, that do not natively support IPFS to access IPFS content. This is a new feature our team has released today in anticipation of our gradual deprecation of our public gateways in October.
Now you are able to create your own unique gateways, dedicated to only your projects. With this initial release, you can also create your own subdomain and restrict your view to show only content you have pinned. These features were previously not available when you accessed IPFS through the public gateway.
CodePudding user response:
As an alternative to Infura, you could use Web3 Storage for IPFS. You don't have to put a credit card down and initial setup is easier than Infura IMO. I'm also assuming your following the JSMastery NFT course. So once you get an API key your client would look like:
const client = new Web3Storage({ token: process.env.WEB_3_STORAGE_KEY });
Then the uploadToIPFS method would be:
const uploadToIPFS = async (files, setFileURL) => {
const cid = await client.put(files);
const url = `https://${cid}.ipfs.w3s.link/${files[0].name}`;
console.log('stored files with cid:', cid);
console.log(url);
return url;
};
In createNFT, storing data such as name, description, and imageURL wont be part of the infura "update" function anymore though, so you'd need to create a blob of that data the link you just created to store the NFT. So within the createNFT function you'll need to adjust the data variable to something like:
const data = new Blob([JSON.stringify({ name, description, image: fileURL, fileID })], { type: 'application/json' });
There's a few other adjustments you'll have to make to your code such as changing trusted NextJS Image sources, and how you link your blob to the image with a unique value but if you go through the Web3 Storage docs you should be able to figure it out.
I kept running into problems with Infura and this works much better now. Feel free to take a look at my code on github. It's part of it's own branch so you can see everything that has the comment "Changed IPFS Provider" to see what was changed to accommodate the switch.