Search code examples
node.jsexpressaxiosbufferipfs

IPFS Pinata service not accepting file


I have a code as shown below that uploads files from the browser and saves in the server, once it has been saved to the server, I want the server to connect to the Pinata API so the file can also be saved to the IPFS node.

  let data = new FormData();

                      const fileBuffer = Buffer.from(`./public/files/${fileName}`, 'utf-8');
                      data.append('file', fileBuffer, `${fileName}`);

                      axios.post('https://api.pinata.cloud/pinning/pinJSONToIPFS',
                          data,
                          {
                              headers: {
                                  'Content-Type': `multipart/form-data; boundary= ${data._boundary}`,
                                  'pinata_api_key': pinataApiKey,
                                  'pinata_secret_api_key': pinataSecretApiKey
                              }
                          }
                      ).then(function (response) {
                          console.log("FILE UPLOADED TO IPFS NODE", fileName);
                          console.log(response);
                      }).catch(function (error) {
                          console.log("FILE WASNT UPLOADED TO IPFS NODE", fileName);
                          console.log(error);
                      });

The issue i'm having is that after creating a buffer of my file and wrapping it in a formdata, the pinata API returns an error :

   data: {
      error: 'This API endpoint requires valid JSON, and a JSON content-type'
    }

If i convert the data to string like JSON.stringify(data) and change the content-type to application/json, the file buffer will be uploaded successfully as string.

I hope explained it well to get a solution. Thanks.


Solution

  • It looks like you're attempting to upload a file to the pinJSONToIPFS endpoint, which is intended to purely be used for JSON that is passed in via a request body.

    In your situation I would recommend using Pinata's pinFileToIPFS endpoint

    Here's some example code based on their documentation that may be of help:

    //imports needed for this function
    const axios = require('axios');
    const fs = require('fs');
    const FormData = require('form-data');
    
    export const pinFileToIPFS = (pinataApiKey, pinataSecretApiKey) => {
        const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
    
        //we gather a local file for this example, but any valid readStream source will work here.
        let data = new FormData();
        data.append('file', fs.createReadStream('./yourfile.png'));
    
        return axios.post(url,
            data,
            {
                maxContentLength: 'Infinity', //this is needed to prevent axios from erroring out with large files
                headers: {
                    'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
                    'pinata_api_key': pinataApiKey,
                    'pinata_secret_api_key': pinataSecretApiKey
                }
            }
        ).then(function (response) {
            //handle response here
        }).catch(function (error) {
            //handle error here
        });
    };