简体   繁体   中英

Saving uploaded file to Pinata IPFS in NodeJS

I've been trying to save uploaded image files to IPFS in NodeJs, while it seems Pinata saves them, the files are pretty much gibberish (after downloading the images are broken).

My code:

// Nodejs route.
exports.postImage = async (req, res, next) => {
    // Using multer to get the file.
    fileUploadMiddleware(req, res, async (err) => {
        // getting bunch of data from query string.
        let meta = {
            origin,
            originid,
            context,
            ownerid,
            format
        } = req.query;

        if(!meta.format || !req.files) {
            return next(new ErrorResponse("File format not specified", 404));
        }

        if(!meta.originid) {
            meta.originid = uuidv4();
        }        
        
        // NOTE: is this the right way to get the data of the file ?
        const buffer = req.files[0].buffer;
        
 const filename = `${metadata.origin}_${metadata.originid}.${ metadata.format }`;

    let stream;
    try {
        stream = Readable.from(buffer);
        // HACK to make PINATA WORK.
        stream.path = filename;
    }
    catch(e) {
        logger.logError(e);
        return false;
    }

    const options = {
        pinataMetadata: {
            name: filename,
            keyvalues: {
                context: metadata.context,
                ownerid: metadata.ownerid
            }
        },
        pinataOptions: {
            cidVersion: 0
        }
    };

    try {
        var result = await pinata.pinFileToIPFS(stream, options);
        console.log("SUCCESS ", result);

        return result;
    }
    catch(e) {
        logger.logError(e);
        return null;
    }

        res.status(200).json({
            success: true,
            data: 'You got access'
        })
    });
}

So basically creating the stream based on the uploaded file buffer and sending it away to Pinata. Where do I go wrong?

const buffer = req.files[0].buffer;

If you used MemoryStorage . buffer property would be available. It is not available for diskStorage because it will save the file locally.:

const storage = multer.memoryStorage()
const upload = multer({ storage: storage })

Also I think it not req.files[0]

const buffer = req.file.buffer;

after I get the buffer, I convert it to FormData using form-data npm package:

   import FormData from "form-data";

   const formData = new FormData();
      formData.append("file", buffer, {
         contentType,
        filename: fileName + "-" + uuidv4(),
      });

then you send a post request to pinata

  const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
  const fileRes = await axios.post(url, formData, {
    maxBodyLength: Infinity,
    headers: {
      // formData.getBoundary() is specific to npm package. native javascript FormData does not have this method
      "Content-Type": `multipart/form-data: boundary=${formData.getBoundary()}`,
      pinata_api_key: pinataApiKey,
      pinata_secret_api_key: pinataSecretApiKey,
    },
  });

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM