Search code examples
javascriptauthenticationamazon-s3aws-lambdaipfs

Pinata IPFS API Keeps denying pinFileToIPFS requests


I keep trying to pin a file from s3 to ipfs.

Pinata keep telling me AccessDenied: Access Denied with a 403 status code.

I get a successful response when I try the /testAuthentication endpoint. I double checked my keys and secrets and even made new accounts to see if it was an account issue. Here's my code :

try {

       await axios.get(testURL, {
      
        headers: {
           
            pinata_api_key: apiKey,
            pinata_secret_api_key: apiSecret,
        }
    })
    .then(function (response) {
        //handle response here
        console.log(response)
    })
    .catch(function (err) {
        //handle error here
        console.log(err);
        throw new Error(err)
    });
  
        const request = JSON.parse(event.body);


        for (const [key, value] of Object.entries(request)) {

            console.log(`${key}: ${value}`);

            
            
        }

        let s3 = new AWS.S3();

        let s3Stream = s3
          .getObject({
            Bucket: s3Bucket,
            Key: fileName,
          })
          .createReadStream();

        let data = new FormData();
        data.append('file', s3Stream, {
                filename: fileName //required or it fails
              });

        await axios.post(url, data, {
        maxBodyLength: '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: apiKey,
            pinata_secret_api_key: apiSecret
        }
    })
    .then(function (response) {
        //handle response here
        return ResponseUtility.Build(200, { Message: "Image was uploaded to IPFS" , url : response});
    })
    .catch(function (err) {
        //handle error here
        console.log(err);
        throw new Error(err)
    });

      
    }
    catch (error) {
  
         return ResponseUtility.Build(500, { Message: error.message });
    }

Solution

  • It turns out The S3 image I was attempting to upload did not Exist. In addition to that, I had to use tweak my Axios request to pin the file.

    Here's my new Code :

      const pinataSDK = require("@pinata/sdk");
      const FormData = require('form-data');
    
      var form = new FormData();
    
        try {
    
            const pinata = pinataSDK(apiKey, apiSecret);
            pinata.testAuthentication().then((result) => {
                console.log("Authenticated ",result);
            }).catch((err) => {
                console.log(err);
                throw new Error(err)
            });
         
            let s3 = new AWS.S3();
            const request = JSON.parse(event.body);
    
    
            for (const [key, value] of Object.entries(request)) {
    
                console.log(`${key}: ${value}`);
    
            }
    
         
            var params = {
                Bucket: s3Bucket,
                Key: fileName
            };
         
        
            try {
              await s3.headObject(params).promise()
              console.log("File Found in S3")
            } catch (err) {
              console.log("File not Found ERROR : " + err)
              throw new Error(err)
            }
    
            let s3Stream =  s3
              .getObject({
                Bucket: s3Bucket,
                Key: fileName,
              })
              .createReadStream();
    
             
                form.append('file', s3Stream, {
                    filename: fileName //required or it fails
                  });
                  
                  var config = {
                    method: 'post',
                    url: url,
                    'maxBodyLength': 'Infinity',
                    headers: {
                      'Content-Type': `multipart/form-data; boundary=${form._boundary}`,
                      'pinata_api_key': apiKey,
                      'pinata_secret_api_key': apiSecret,
                      ...form.getHeaders()
                    },
                    data: form
                  };
                  
                let res =  await axios(config)
    
            
                if (res.status === 200 && res.data)
                    return ResponseUtility.Build(200, res.data);
                else
                    throw new Error(JSON.stringify({statusCode : res.status, Message : "Error occured while uploading file to IPFS"}))   
                
                }
        catch (error) {
            
             return ResponseUtility.Build(500, { Message: error.message ? error.message : error });
        }