From 2207a4c927c3f8e27bd458fa21f001a2933a6742 Mon Sep 17 00:00:00 2001 From: Albert Folch Date: Mon, 5 Aug 2024 16:49:54 +0200 Subject: [PATCH] feat: add asBlob parameter to baseIpfsStorage to retrieve ipfs item as a blob --- packages/ipfs-storage/src/ipfs/base.ts | 79 ++++++++++++++++--- packages/ipfs-storage/src/ipfs/metadata.ts | 4 +- .../form/Upload/WithUploadToIpfs.tsx | 4 +- .../react-kit/src/hooks/useRenderTemplate.ts | 5 +- packages/react-kit/src/lib/base64/base64.ts | 6 +- 5 files changed, 75 insertions(+), 23 deletions(-) diff --git a/packages/ipfs-storage/src/ipfs/base.ts b/packages/ipfs-storage/src/ipfs/base.ts index aa2fef422..02f1069cd 100644 --- a/packages/ipfs-storage/src/ipfs/base.ts +++ b/packages/ipfs-storage/src/ipfs/base.ts @@ -21,7 +21,11 @@ export class BaseIpfsStorage { return cid; } - public async get(uriOrHash: string, asJson = true): Promise { + public async get( + uriOrHash: string, + asJson = true, + asBlob = false + ): Promise { let cid: CID = null; try { cid = CID.parse( @@ -34,30 +38,79 @@ export class BaseIpfsStorage { } const value = await (cid - ? this.getByCID(cid.toString(), asJson) - : this.getByURL(uriOrHash, asJson)); + ? this.getByCID(cid.toString(), asJson, asBlob) + : this.getByURL(uriOrHash, asJson, asBlob)); return value; } - - public async getByCID(cid: string, asJson = true): Promise { + public async getByCID( + cid: string, + asJson: true, + asBlob: false + ): Promise; + public async getByCID( + cid: string, + asJson: false, + asBlob: true + ): Promise; + public async getByCID( + cid: string, + asJson: false, + asBlob: false + ): Promise; + public async getByCID( + cid: string, + asJson: boolean, + asBlob: boolean + ): Promise; + public async getByCID( + cid: string, + asJson = true, + asBlob = false + ): Promise { const chunks = []; for await (const chunk of this.ipfsClient.cat(cid)) { chunks.push(chunk); } const data = concat(chunks); - if (!asJson) { - return data as unknown as T; + if (!asJson && asBlob) { + return new Blob([data]); + } else if (!asJson) { + return data; } const dataStr = toString(data); - return JSON.parse(dataStr); + return JSON.parse(dataStr) as T; } - - public async getByURL(url: string, asJson = true): Promise { + public async getByURL( + url: string, + asJson: true, + asBlob: false + ): Promise; + public async getByURL( + url: string, + asJson: false, + asBlob: true + ): Promise; + public async getByURL( + url: string, + asJson: false, + asBlob: false + ): Promise; + public async getByURL( + url: string, + asJson: boolean, + asBlob: boolean + ): Promise; + public async getByURL( + url: string, + asJson = true, + asBlob = false + ): Promise { const response = await fetch(url); - - if (!asJson) { + if (!asJson && asBlob) { + return response.blob(); + } else if (!asJson) { return response.text(); } - return response.json(); + return response.json() as T; } } diff --git a/packages/ipfs-storage/src/ipfs/metadata.ts b/packages/ipfs-storage/src/ipfs/metadata.ts index 405cbe5c7..8dba80cf7 100644 --- a/packages/ipfs-storage/src/ipfs/metadata.ts +++ b/packages/ipfs-storage/src/ipfs/metadata.ts @@ -41,9 +41,9 @@ export class IpfsMetadataStorage * @returns Offer metadata. */ public async getMetadata(metadataUriOrHash: string): Promise { - const metadata = (await this.get( + const metadata = (await this.get( metadataUriOrHash - )) as ERC721Metadata; + )) as unknown as ERC721Metadata; if (metadata.type) { this.validateMetadata(metadata); } diff --git a/packages/react-kit/src/components/form/Upload/WithUploadToIpfs.tsx b/packages/react-kit/src/components/form/Upload/WithUploadToIpfs.tsx index 468bc9f48..45c063fa6 100644 --- a/packages/react-kit/src/components/form/Upload/WithUploadToIpfs.tsx +++ b/packages/react-kit/src/components/form/Upload/WithUploadToIpfs.tsx @@ -24,8 +24,8 @@ export interface WithUploadToIpfsProps { saveToIpfs: ( files: File[] | null ) => Promise; - loadMedia: (src: string) => string; - removeFile: (src: string) => void; + loadMedia: (src: string) => Promise; + removeFile: (src: string) => Promise; } export function WithUploadToIpfs

( WrappedComponent: React.ComponentType

diff --git a/packages/react-kit/src/hooks/useRenderTemplate.ts b/packages/react-kit/src/hooks/useRenderTemplate.ts index 489e11ba2..5fdcb8487 100644 --- a/packages/react-kit/src/hooks/useRenderTemplate.ts +++ b/packages/react-kit/src/hooks/useRenderTemplate.ts @@ -28,10 +28,11 @@ export function useRenderTemplate( setRenderStatus(ProgressStatus.LOADING); if (ipfsMetadataStorage && coreSDK) { try { - const rawTemplate = await ipfsMetadataStorage.get( + const rawTemplate = (await ipfsMetadataStorage.get( templateUrl, + false, false - ); + )) as Uint8Array; const template = Buffer.from(rawTemplate).toString("utf-8"); let theOfferData = offerData; // If the offerData is not specified, retrieve the data from offerId diff --git a/packages/react-kit/src/lib/base64/base64.ts b/packages/react-kit/src/lib/base64/base64.ts index 2816de864..5ce7a6658 100644 --- a/packages/react-kit/src/lib/base64/base64.ts +++ b/packages/react-kit/src/lib/base64/base64.ts @@ -48,10 +48,8 @@ export const fetchIpfsBase64Media = async ( return []; } const fetchPromises = ipfsLinks.map(async (src) => { - const imgData = await ipfsMetadataStorage.get(src, false); - const base64str = await blobToBase64( - new Blob([imgData as unknown as BlobPart]) - ); + const imgData = await ipfsMetadataStorage.get(src, false, true); + const base64str = await blobToBase64(new Blob([imgData])); if (!String(base64str).includes("base64")) { throw new Error("Decoded image is not in base64"); }