From 7705105080cb97416619186cfebc02d9d42f949c Mon Sep 17 00:00:00 2001 From: Tom Quirk <12551741+tomquirk@users.noreply.github.com> Date: Thu, 1 Feb 2024 11:04:50 +1000 Subject: [PATCH] feat: start proxying ipfs requests (#4242) --- .../JB721Delegate/useNftCollectionMetadata.ts | 4 +-- src/hooks/useProjectMetadata.ts | 5 ++-- src/lib/api/ipfs.ts | 14 ++++++++++ src/pages/api/ipfs/[cid].ts | 27 +++++++++++++++++++ 4 files changed, 45 insertions(+), 5 deletions(-) create mode 100644 src/pages/api/ipfs/[cid].ts diff --git a/src/hooks/JB721Delegate/useNftCollectionMetadata.ts b/src/hooks/JB721Delegate/useNftCollectionMetadata.ts index e5dc3054a0..50a4e5db20 100644 --- a/src/hooks/JB721Delegate/useNftCollectionMetadata.ts +++ b/src/hooks/JB721Delegate/useNftCollectionMetadata.ts @@ -1,4 +1,4 @@ -import { ipfsGatewayFetch } from 'lib/api/ipfs' +import { ipfsFetch } from 'lib/api/ipfs' import { NftCollectionMetadata } from 'models/nftRewards' import { useQuery } from 'react-query' import { cidFromUrl } from 'utils/ipfs' @@ -17,7 +17,7 @@ export function useNftCollectionMetadata(uri: string | undefined) { throw new Error('NFT Contract URI invalid.') } - const response = await ipfsGatewayFetch(cid) + const response = await ipfsFetch(cid) return response.data }, { diff --git a/src/hooks/useProjectMetadata.ts b/src/hooks/useProjectMetadata.ts index 30d08d9ecf..b232265bef 100644 --- a/src/hooks/useProjectMetadata.ts +++ b/src/hooks/useProjectMetadata.ts @@ -1,4 +1,4 @@ -import { ipfsGatewayFetch } from 'lib/api/ipfs' +import { ipfsFetch } from 'lib/api/ipfs' import { AnyProjectMetadata, consolidateMetadata } from 'models/projectMetadata' import { useQuery } from 'react-query' @@ -10,13 +10,12 @@ export function useProjectMetadata(uri: string | null | undefined) { throw new Error('Project URI not specified.') } - const response = await ipfsGatewayFetch(uri) + const response = await ipfsFetch(uri) const metadata = consolidateMetadata(response.data) return metadata }, { enabled: !!uri, - staleTime: 60000, }, ) } diff --git a/src/lib/api/ipfs.ts b/src/lib/api/ipfs.ts index 44c17d62bf..9f4f5f0fa5 100644 --- a/src/lib/api/ipfs.ts +++ b/src/lib/api/ipfs.ts @@ -20,6 +20,20 @@ const extractJsonFromBase64Data = (base64: string) => { return JSON.parse(decoded.substring(jsonStart, jsonEnd + 1)) } +/** + * Fetch an IPFS hash from our proxy. + */ +export const ipfsFetch = async (hash: string) => { + const response = await axios.get( + `${process.env.NEXT_PUBLIC_BASE_URL}api/ipfs/${hash}`, + ) + + return response +} + +/** + * Fetch an IPFS hash directly from the IPFS gateway. + */ export const ipfsGatewayFetch = async ( hash: string, opts?: AxiosRequestConfig, diff --git a/src/pages/api/ipfs/[cid].ts b/src/pages/api/ipfs/[cid].ts new file mode 100644 index 0000000000..928c7bebcf --- /dev/null +++ b/src/pages/api/ipfs/[cid].ts @@ -0,0 +1,27 @@ +import { ipfsGatewayFetch } from 'lib/api/ipfs' +import { getLogger } from 'lib/logger' +import { NextApiRequest, NextApiResponse } from 'next' + +const logger = getLogger('ipfs/[cid]') + +export default async function handler( + req: NextApiRequest, + res: NextApiResponse, +) { + if (req.method !== 'GET') { + return res.status(405).end() + } + if (!req.query.cid) { + return res.status(400).json({ error: 'cid not specified' }) + } + + try { + const ipfsRes = await ipfsGatewayFetch(req.query.cid as string) + // cache for 1 day + res.setHeader('Cache-Control', 's-maxage=86400, stale-while-revalidate') + return res.status(200).json(ipfsRes.data) + } catch (error) { + logger.error(error) + return res.status(500).json({ error: 'failed to fetch ipfs data' }) + } +}