Skip to content

Commit af91f36

Browse files
fix ipfs load times
1 parent bb3ffa9 commit af91f36

File tree

7 files changed

+143
-130
lines changed

7 files changed

+143
-130
lines changed

components/NFTCard.tsx

+10-8
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import Image from 'next/image'
22
import { MintingContractProps } from '../utils/ContractHelper'
3-
import { useParseIpfsImage } from '../utils/AxiosHelper'
43
import { useState, useEffect } from 'react'
54
import { useContractRead } from 'wagmi'
65
import MintingContractJSON from '../artifacts/contracts/MitchMinterSupplyUpgradeable.sol/MitchMinter.json'
76
import { formatEther } from 'viem'
7+
import { getIpfsImage } from '../utils/AxiosHelper'
88

99

1010
interface NFTCardProps {
@@ -45,11 +45,6 @@ export const NFTCard: React.FC<NFTCardProps> = ({
4545
setToggleText(!toggleText)
4646
}
4747

48-
const newIpfsImage = useParseIpfsImage(tokenId, contractProps)
49-
// const newIpfsData = useParseIpfsData(tokenId, contractProps)
50-
51-
// const tokenName = ipfsData.name
52-
// const tokenDescription = ipfsData.description
5348
const tokenID = tokenId
5449

5550
const maxTokenSupply = useContractRead({
@@ -91,6 +86,8 @@ export const NFTCard: React.FC<NFTCardProps> = ({
9186
// enabled: false,
9287
// })
9388

89+
90+
9491
useEffect(() => {
9592
setTimeout(() => {
9693
maxTokenSupply.refetch()
@@ -172,8 +169,13 @@ export const NFTCard: React.FC<NFTCardProps> = ({
172169
}, [tokenInfo, isTokenInfoError])
173170

174171
useEffect(() => {
175-
setIpfsImage(newIpfsImage)
176-
}, [newIpfsImage])
172+
if (image) {
173+
getIpfsImage(image).then((res) => {
174+
setIpfsImage(res)
175+
}
176+
)
177+
}
178+
},[image])
177179

178180
useEffect(() => {
179181
setTokenSymbol(paymentTokenSymbol)

components/mint.tsx

-3
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,10 @@ export const MintModal = ({
5252
userBalance,
5353
nftData
5454
}: MintItems) => {
55-
console.log('nftData', nftData)
5655
const tokenId = itemsArray[0].tokenID
5756
const twitterLink = contractProps.nftExplorerLink + '0x' + contractProps.address + '/' + tokenId
5857
const tokenBatchIds = itemsArray.map((item) => item.tokenID)
5958
const tokenLinks = itemsArray.map((item) => (
60-
console.log('item', nftData[item.tokenID - 1]?.name),
61-
console.log('item', item.tokenID),
6259
<li className="text-purple-600 py-1 text-lg hover:text-purple-700 font-bold" key={item.tokenID}>
6360
{' '}
6461
<a

package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"@nomiclabs/hardhat-waffle": "^2.0.3",
2121
"@openzeppelin/contracts": "^4.7.2",
2222
"@openzeppelin/contracts-upgradeable": "npm:@openzeppelin/contracts-upgradeable",
23-
"@rainbow-me/rainbowkit": "1",
23+
"@rainbow-me/rainbowkit": "^1.0.11",
2424
"@tailwindcss/forms": "^0.5.2",
2525
"@types/react-modal": "^3.13.1",
2626
"@vercel/analytics": "^1.0.1",
@@ -43,7 +43,7 @@
4343
"unstated-next": "^1.1.0",
4444
"usehooks-ts": "^2.9.1",
4545
"viem": "1.7.0",
46-
"wagmi": "1",
46+
"wagmi": "1.4.1",
4747
"yarn": "^1.22.19"
4848
},
4949
"devDependencies": {

pages/_app.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import {infuraProvider} from 'wagmi/providers/infura'
1111
import { constants } from '../utils/constants'
1212
import { Analytics } from '@vercel/analytics/react'
1313
import { jsonRpcProvider } from 'wagmi/providers/jsonRpc'
14+
import { publicProvider } from 'wagmi/providers/public';
1415

1516

1617
const walletConnectId = process.env.WALLET_CONNECT_PROJECT as string
@@ -30,6 +31,7 @@ if (process.env.NODE_ENV === 'development') {
3031
const { chains, publicClient } = configureChains(appChains, [
3132
infuraProvider({ apiKey: infuraID}),
3233
jsonRpcProvider({ rpc: () => ({ http: NEXT_PUBLIC_GNOSIS_RPC_URL }) }),
34+
publicProvider(),
3335
])
3436

3537
const { connectors } = getDefaultWallets({

pages/store.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ interface Item {
2222
tokenPrice: string
2323
}
2424

25-
interface nftData {
25+
export interface nftData {
2626
name: string
2727
description: string
2828
image: string
@@ -143,8 +143,9 @@ const Store = () => {
143143
try {
144144
const allNftData: nftData[] = [];
145145
for(let i = 1; i <= totalTokens; i++) {
146-
const response = await getIpfsData(i, contractProps);
146+
getIpfsData(i, contractProps).then((response) => {
147147
allNftData.push(response);
148+
0 })
148149
}
149150
return allNftData;
150151
} catch (error) {

utils/AxiosHelper.tsx

+108-91
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import MintingContractJSON from '../artifacts/contracts/MitchMinterSupplyUpgrade
66
import { useContractRead } from 'wagmi';
77
import { constants } from './constants';
88
import { readContract } from '@wagmi/core';
9+
import { nftData } from '../pages/store';
910

1011
const ipfsGateways = constants.IPFS_GATEWAYS!.split(',');
1112

@@ -23,7 +24,7 @@ async function getDataFromGateways(path: any) {
2324
throw new Error('All gateways failed');
2425
}
2526

26-
export const getIpfsData = async (tokenId: number, contractProps: MintingContractProps) => {
27+
export const getIpfsData = async (tokenId: number, contractProps: MintingContractProps): Promise<nftData> => {
2728
try {
2829
const tokenInfo = await readContract({
2930
address: `0x${contractProps.address}`,
@@ -35,118 +36,134 @@ export const getIpfsData = async (tokenId: number, contractProps: MintingContrac
3536

3637
const [, tokenURI] = tokenInfo as [string, string];
3738
const tokenCID = tokenURI.replace("ipfs://", "");
38-
3939
const response = await getDataFromGateways(tokenCID);
4040

4141
const metaData = {
4242
name: response.data.name,
4343
description: response.data.description,
4444
image: response.data.image,
4545
tokenId: tokenId,
46-
}
47-
;
46+
};
47+
48+
return metaData;
4849

49-
return metaData
5050
} catch (error) {
5151
console.error(error);
5252
throw error; // You can choose to rethrow the error or handle it here
5353
}
5454
};
5555

5656

57-
export const useParseIpfsData = (tokenId: number, contractProps: MintingContractProps) => {
58-
const debouncedContractProps = useDebounce(contractProps, 500);
59-
const [ipfsData, setIpfsData] = useState({
60-
name: 'Loading...',
61-
description: 'Loading...',
62-
});
63-
const {data: tokenInfo, isSuccess: isTokenInfoSuccess, isError: isTokenInfoError, error: tokenInfoError } = useContractRead({
64-
address: `0x${debouncedContractProps.address}`,
65-
abi: MintingContractJSON.abi,
66-
functionName: 'getTokenInfo',
67-
args: [tokenId],
68-
chainId: debouncedContractProps.chainId
69-
});
70-
const retrieveIpfsData = useCallback(async () => {
71-
if (isTokenInfoSuccess && tokenInfo) {
72-
const [, tokenURI] = tokenInfo as [string, string]
73-
const tokenCID = tokenURI.replace("ipfs://", "");
74-
try {
75-
const response = await getDataFromGateways(tokenCID);
76-
const metaData = {
77-
name: response.data.name,
78-
description: response.data.description,
79-
image: response.data.image,
80-
};
81-
setIpfsData(metaData);
82-
} catch (error) {
83-
console.error(error);
84-
}
85-
} else if (isTokenInfoError) {
86-
console.log(tokenInfoError)
87-
}
88-
}, [isTokenInfoSuccess, isTokenInfoError, tokenInfo]);
57+
58+
// export const useParseIpfsData = (tokenId: number, contractProps: MintingContractProps) => {
59+
// const debouncedContractProps = useDebounce(contractProps, 500);
60+
// const [ipfsData, setIpfsData] = useState({
61+
// name: 'Loading...',
62+
// description: 'Loading...',
63+
// });
64+
// const {data: tokenInfo, isSuccess: isTokenInfoSuccess, isError: isTokenInfoError, error: tokenInfoError } = useContractRead({
65+
// address: `0x${debouncedContractProps.address}`,
66+
// abi: MintingContractJSON.abi,
67+
// functionName: 'getTokenInfo',
68+
// args: [tokenId],
69+
// chainId: debouncedContractProps.chainId
70+
// });
71+
// const retrieveIpfsData = useCallback(async () => {
72+
// if (isTokenInfoSuccess && tokenInfo) {
73+
// const [, tokenURI] = tokenInfo as [string, string]
74+
// const tokenCID = tokenURI.replace("ipfs://", "");
75+
// try {
76+
// const response = await getDataFromGateways(tokenCID);
77+
// const metaData = {
78+
// name: response.data.name,
79+
// description: response.data.description,
80+
// image: response.data.image,
81+
// };
82+
// setIpfsData(metaData);
83+
// } catch (error) {
84+
// console.error(error);
85+
// }
86+
// } else if (isTokenInfoError) {
87+
// console.log(tokenInfoError)
88+
// }
89+
// }, [isTokenInfoSuccess, isTokenInfoError, tokenInfo]);
8990

90-
useEffect(() => {
91-
retrieveIpfsData();
92-
}, [retrieveIpfsData]);
91+
// useEffect(() => {
92+
// retrieveIpfsData();
93+
// }, [retrieveIpfsData]);
9394

94-
return ipfsData;
95-
};
96-
97-
98-
export const useParseIpfsImage = (tokenId: number, contractProps: MintingContractProps) => {
99-
const debouncedContractProps = useDebounce(contractProps, 500);
100-
const [ipfsImage, setIpfsImage] = useState('');
101-
const {data: tokenInfo, isSuccess: isTokenInfoSuccess, isError: isTokenInfoError, error: tokenInfoError } = useContractRead({
102-
address: `0x${debouncedContractProps.address}`,
103-
abi: MintingContractJSON.abi,
104-
functionName: 'getTokenInfo',
105-
args: [tokenId],
106-
chainId: debouncedContractProps.chainId
107-
});
108-
109-
110-
// const IPFS_GATEWAYS = process.env.IPFS_GATEWAYS!.split(',');
111-
95+
// return ipfsData;
96+
// };
11297

113-
const getImageFromGateways = async (cid: string, gateways: string[]) => {
114-
for (const gateway of gateways) {
115-
try {
116-
const response = await axios.get(`${gateway}/${cid}`, { responseType: 'arraybuffer' }, { timeout: 5000 });
117-
return response;
118-
} catch (error) {
119-
console.error(`Failed to fetch from ${gateway}`, error);
120-
}
98+
export const getIpfsImage = async (ipfsHash: string) => {
99+
const tokenCID = ipfsHash.replace("ipfs://", "");
100+
let imageResponse: any
101+
for (const gateway of ipfsGateways) {
102+
try {
103+
const response = await axios.get(`${gateway}/${tokenCID}`, { responseType: 'arraybuffer' }, { timeout: 5000 });
104+
imageResponse = await response;
105+
const imageBuffer = Buffer.from(imageResponse.data, 'binary');
106+
const imageSrc = 'data:image/jpeg;base64,' + imageBuffer.toString('base64');
107+
return imageSrc
108+
} catch (error) {
109+
console.error(`Failed to fetch from ${gateway}`, error);
121110
}
122-
throw new Error(`Failed to fetch data from all gateways for CID: ${cid}`);
111+
}
123112
};
124113

125-
const retrieveIpfsData = useCallback(async () => {
126-
if (isTokenInfoSuccess && tokenInfo) {
127-
const [, tokenURI] = tokenInfo as [string, string]
128-
const tokenCID = tokenURI.replace("ipfs://", "");
129-
try {
130-
const response = await getDataFromGateways(tokenCID);
131-
const imgHash = response.data.image.replace("ipfs://", "");
132-
const imageResponse = await getImageFromGateways(imgHash, ipfsGateways);
133-
const imageBuffer = Buffer.from(imageResponse.data, 'binary');
134-
const imageSrc = 'data:image/jpeg;base64,' + imageBuffer.toString('base64');
135-
setIpfsImage(imageSrc);
136-
} catch (error) {
137-
console.error(error);
138-
}
139-
} else if (isTokenInfoError) {
140-
console.log(tokenInfoError)
141-
}
142-
}, [ipfsGateways, isTokenInfoSuccess, isTokenInfoError]);
143-
144-
useEffect(() => {
145-
retrieveIpfsData();
146-
}, [retrieveIpfsData]);
147114

148-
return ipfsImage;
149-
};
115+
// export const useParseIpfsImage = (tokenId: number, contractProps: MintingContractProps) => {
116+
// const debouncedContractProps = useDebounce(contractProps, 200);
117+
// const [ipfsImage, setIpfsImage] = useState('');
118+
// const {data: tokenInfo, isSuccess: isTokenInfoSuccess, isError: isTokenInfoError, error: tokenInfoError } = useContractRead({
119+
// address: `0x${debouncedContractProps.address}`,
120+
// abi: MintingContractJSON.abi,
121+
// functionName: 'getTokenInfo',
122+
// args: [tokenId],
123+
// chainId: debouncedContractProps.chainId
124+
// });
125+
126+
127+
// // const IPFS_GATEWAYS = process.env.IPFS_GATEWAYS!.split(',');
128+
129+
130+
// const getImageFromGateways = async (cid: string, gateways: string[]) => {
131+
// for (const gateway of gateways) {
132+
// try {
133+
// const response = await axios.get(`${gateway}/${cid}`, { responseType: 'arraybuffer' }, { timeout: 5000 });
134+
// return response;
135+
// } catch (error) {
136+
// console.error(`Failed to fetch from ${gateway}`, error);
137+
// }
138+
// }
139+
// throw new Error(`Failed to fetch data from all gateways for CID: ${cid}`);
140+
// };
141+
142+
// const retrieveIpfsData = useCallback(async () => {
143+
// if (isTokenInfoSuccess && tokenInfo) {
144+
// const [, tokenURI] = tokenInfo as [string, string]
145+
// const tokenCID = tokenURI.replace("ipfs://", "");
146+
// try {
147+
// const response = await getDataFromGateways(tokenCID);
148+
// const imgHash = response.data.image.replace("ipfs://", "");
149+
// const imageResponse = await getImageFromGateways(imgHash, ipfsGateways);
150+
// const imageBuffer = Buffer.from(imageResponse.data, 'binary');
151+
// const imageSrc = 'data:image/jpeg;base64,' + imageBuffer.toString('base64');
152+
// setIpfsImage(imageSrc);
153+
// } catch (error) {
154+
// console.error(error);
155+
// }
156+
// } else if (isTokenInfoError) {
157+
// console.log(tokenInfoError)
158+
// }
159+
// }, [ipfsGateways, isTokenInfoSuccess, isTokenInfoError]);
160+
161+
// useEffect(() => {
162+
// retrieveIpfsData();
163+
// }, [retrieveIpfsData]);
164+
165+
// return ipfsImage;
166+
// };
150167

151168

152169

0 commit comments

Comments
 (0)