From 4fca91df4a6aff7d658606d671cf41824cc6dcab Mon Sep 17 00:00:00 2001 From: 1M4nt0 Date: Mon, 5 Feb 2024 22:18:25 +0100 Subject: [PATCH 1/2] added pinata as ipfs provider --- apps/web/lib/ipfs/client.ts | 7 +-- apps/web/pages/api/v0/course/index.ts | 18 ++---- apps/web/pages/api/v0/course/metadata.ts | 3 +- packages/ipfs/src/connectors/infura.ts | 4 +- packages/ipfs/src/connectors/pinata.ts | 80 ++++++++++++++++++++++++ packages/ipfs/src/index.ts | 5 +- 6 files changed, 96 insertions(+), 21 deletions(-) create mode 100644 packages/ipfs/src/connectors/pinata.ts diff --git a/apps/web/lib/ipfs/client.ts b/apps/web/lib/ipfs/client.ts index 37888683..3bcd0562 100644 --- a/apps/web/lib/ipfs/client.ts +++ b/apps/web/lib/ipfs/client.ts @@ -1,7 +1,6 @@ -import { InfuraIpfsConnector } from '@dae/ipfs' +import { PinataIpfsConnector } from '@dae/ipfs' -export const IpfsConnector = new InfuraIpfsConnector( - process.env.INFURA_IPFS_API_KEY ?? '', - process.env.INFURA_IPFS_API_SECRET ?? '', +export const IpfsConnector = new PinataIpfsConnector( process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL ?? '', + process.env.PINATA_JWT_TOKEN ?? '', ) diff --git a/apps/web/pages/api/v0/course/index.ts b/apps/web/pages/api/v0/course/index.ts index c56a7290..408927e5 100644 --- a/apps/web/pages/api/v0/course/index.ts +++ b/apps/web/pages/api/v0/course/index.ts @@ -167,10 +167,8 @@ const handlePostRequest = async ( data: { name: 'Admin', description: 'The course Admin credential', - image_url: - 'https://dae-demo.infura-ipfs.io/ipfs/QmXibYJSXskaqS7WyXLGwy16vGASqhN75yNUp2UfMRiLkF', - ipfs_url: - 'https://dae-demo.infura-ipfs.io/ipfs/QmWNqAC88Sbti885sSbax9RK1Sfbo3akVeue5SMEhXWbjN', + image_url: `${process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL}/QmXibYJSXskaqS7WyXLGwy16vGASqhN75yNUp2UfMRiLkF`, + ipfs_url: `${process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL}/QmWNqAC88Sbti885sSbax9RK1Sfbo3akVeue5SMEhXWbjN`, ipfs_cid: 'QmWNqAC88Sbti885sSbax9RK1Sfbo3akVeue5SMEhXWbjN', type: 'ADMIN', course: { @@ -187,10 +185,8 @@ const handlePostRequest = async ( data: { name: 'Magister', description: 'The course Magister credential', - image_url: - 'https://dae-demo.infura-ipfs.io/ipfs/QmTFVE4FoPJm2vazgVtKajbw2XSNtM2wTDrkUinxMcLbBg', - ipfs_url: - 'https://dae-demo.infura-ipfs.io/ipfs/QmXRAu1zZ7igsNWo8egMDH3g77vFQgZHfcE2k6hoJp4JwT', + image_url: `${process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL}/QmTFVE4FoPJm2vazgVtKajbw2XSNtM2wTDrkUinxMcLbBg`, + ipfs_url: `${process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL}/QmXRAu1zZ7igsNWo8egMDH3g77vFQgZHfcE2k6hoJp4JwT`, ipfs_cid: 'QmXRAu1zZ7igsNWo8egMDH3g77vFQgZHfcE2k6hoJp4JwT', type: 'MAGISTER', course: { @@ -207,10 +203,8 @@ const handlePostRequest = async ( data: { name: 'Discipulus', description: 'The course Discipulus credential', - image_url: - 'https://dae-demo.infura-ipfs.io/ipfs/QmUEC1WiGo9Vr3WER68u3T6mSwLexyDXj5G6WUgpVECmBY', - ipfs_url: - 'https://dae-demo.infura-ipfs.io/ipfs/QmPfKCv7ZAz8294ShRTcHft5LSM9YaDJ4NTjZisCkhFxW8', + image_url: `${process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL}/QmUEC1WiGo9Vr3WER68u3T6mSwLexyDXj5G6WUgpVECmBY`, + ipfs_url: `${process.env.NEXT_PUBLIC_IPFS_GATEWAY_URL}/QmPfKCv7ZAz8294ShRTcHft5LSM9YaDJ4NTjZisCkhFxW8`, ipfs_cid: 'QmPfKCv7ZAz8294ShRTcHft5LSM9YaDJ4NTjZisCkhFxW8', type: 'DISCIPULUS', course: { diff --git a/apps/web/pages/api/v0/course/metadata.ts b/apps/web/pages/api/v0/course/metadata.ts index 61cd824c..4e9e6c67 100644 --- a/apps/web/pages/api/v0/course/metadata.ts +++ b/apps/web/pages/api/v0/course/metadata.ts @@ -32,7 +32,6 @@ const handlePostRequest = async ( } const { mimetype, filepath, originalFilename } = imageFile - console.log(originalFilename) const courseImageBuffer = fs.readFileSync(filepath) const ipfsCourseImageData = await IpfsConnector.upload({ @@ -51,7 +50,7 @@ const handlePostRequest = async ( 'media-channel': mediaChannel, }, fileName: '', - mimeType: 'data/json', + mimeType: 'application/json', }) res.status(200).json({ diff --git a/packages/ipfs/src/connectors/infura.ts b/packages/ipfs/src/connectors/infura.ts index b60f3dee..442e1109 100644 --- a/packages/ipfs/src/connectors/infura.ts +++ b/packages/ipfs/src/connectors/infura.ts @@ -2,7 +2,9 @@ import axios from 'axios' import FormData from 'form-data' import { IpfsConnector, IpfsUploadResult } from '../' -export class InfuraIpfsConnector implements IpfsConnector { +export class InfuraIpfsConnector + implements IpfsConnector> +{ private apiKey: string private apiSecret: string private authToken: string diff --git a/packages/ipfs/src/connectors/pinata.ts b/packages/ipfs/src/connectors/pinata.ts new file mode 100644 index 00000000..d7efcb31 --- /dev/null +++ b/packages/ipfs/src/connectors/pinata.ts @@ -0,0 +1,80 @@ +import axios from 'axios' +import FormData from 'form-data' +import { IpfsConnector, IpfsUploadResult } from '../' +import { Readable } from 'stream' + +export class PinataIpfsConnector + implements IpfsConnector> +{ + private ipfsGateway: string + private JWT: string + + constructor(ipfsGateway: string, jwtToken: string) { + this.ipfsGateway = ipfsGateway + this.JWT = jwtToken + } + + public async upload({ + fileContent, + fileName, + mimeType, + }: { + fileContent: Buffer | Record + fileName: string + mimeType: string + }): Promise { + const formData = new FormData() + let response = null + + if (fileContent instanceof Buffer) { + console.log(fileName) + const stream = Readable.from(fileContent) + formData.append('file', stream, { + filepath: fileName, + contentType: mimeType, + }) + response = await axios.post( + 'https://api.pinata.cloud/pinning/pinFileToIPFS', + formData, + { + maxBodyLength: Infinity, + headers: { + 'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`, + Authorization: `Bearer ${this.JWT}`, + }, + }, + ) + } else if (typeof fileContent === 'object') { + response = await axios.post( + 'https://api.pinata.cloud/pinning/pinJSONToIPFS', + fileContent, + { + headers: { + accept: 'application/json', + 'content-type': 'application/json', + Authorization: `Bearer ${this.JWT}`, + }, + }, + ) + } else { + throw new Error('File type not supported.') + } + + if (response.status !== 200) { + throw Error('Error uploading files to IPFS.') + } + + const data = response.data as { + IpfsHash: string + PinSize: string + Timestamp: string + } + + return { + hash: data.IpfsHash, + size: data.PinSize, + name: fileName, + url: `${this.ipfsGateway}/${data.IpfsHash}`, + } + } +} diff --git a/packages/ipfs/src/index.ts b/packages/ipfs/src/index.ts index 3a038168..5579ec31 100644 --- a/packages/ipfs/src/index.ts +++ b/packages/ipfs/src/index.ts @@ -1,4 +1,5 @@ export * from './connectors/infura' +export * from './connectors/pinata' export type IpfsUploadResult = { hash: string @@ -8,13 +9,13 @@ export type IpfsUploadResult = { timestamp?: number } -export interface IpfsConnector { +export interface IpfsConnector { upload({ fileContent, mimeType, fileName, }: { - fileContent: Buffer | Record + fileContent: T mimeType?: string fileName?: string }): Promise From ff1fe562bd00b9075f09630f8015d36cff5f0da4 Mon Sep 17 00:00:00 2001 From: 1M4nt0 Date: Mon, 5 Feb 2024 22:56:38 +0100 Subject: [PATCH 2/2] updated snapshot.js deps --- packages/snapshot/package.json | 2 +- packages/ui/package.json | 2 +- pnpm-lock.yaml | 12 ++++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/snapshot/package.json b/packages/snapshot/package.json index 1415df05..8318ccee 100644 --- a/packages/snapshot/package.json +++ b/packages/snapshot/package.json @@ -8,7 +8,7 @@ "clean": "rm -rf .turbo && rm -rf node_modules && rm -rf dist" }, "dependencies": { - "@snapshot-labs/snapshot.js": "0.9.6", + "@snapshot-labs/snapshot.js": "0.10.1", "ethers": "5.7.2", "graphql": "16.8.1", "graphql-request": "6.1.0", diff --git a/packages/ui/package.json b/packages/ui/package.json index 5f4254ac..2906b84d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -34,7 +34,7 @@ "@dae/wagmi": "workspace:*", "@emotion/react": "11.11.1", "@emotion/styled": "11.11.0", - "@snapshot-labs/snapshot.js": "0.9.6", + "@snapshot-labs/snapshot.js": "0.10.1", "@types/papaparse": "5.3.11", "@types/react": "18.2.37", "@types/react-dom": "18.2.15", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8402e2de..eae9078a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -307,8 +307,8 @@ importers: packages/snapshot: dependencies: '@snapshot-labs/snapshot.js': - specifier: 0.9.6 - version: 0.9.6 + specifier: 0.10.1 + version: 0.10.1 ethers: specifier: 5.7.2 version: 5.7.2 @@ -458,8 +458,8 @@ importers: specifier: 11.11.0 version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.2.37)(react@18.2.0) '@snapshot-labs/snapshot.js': - specifier: 0.9.6 - version: 0.9.6 + specifier: 0.10.1 + version: 0.10.1 '@types/papaparse': specifier: 5.3.11 version: 5.3.11 @@ -2735,8 +2735,8 @@ packages: '@noble/hashes': 1.3.2 '@scure/base': 1.1.3 - /@snapshot-labs/snapshot.js@0.9.6: - resolution: {integrity: sha512-xO4H9p+to/17hYSbsQpiG29+iEzQf00wRzG+G+Cx/+0/KxkyMoGQhZuZqm9zxYHjtmCBiEY6dITbu38A/n0lmA==} + /@snapshot-labs/snapshot.js@0.10.1: + resolution: {integrity: sha512-PacD8HdsYZhb1Yifp6n+11Og+nZUvGhTosu+ejnEwhP6zQOFMg6gaIEsWGjoAMnjos0sgA/oIbWdPIzqJRTECw==} engines: {node: '>=14'} dependencies: '@ensdomains/eth-ens-namehash': 2.0.15