All files / src/storage ipfs.ts

73.8% Statements 31/42
62.5% Branches 5/8
100% Functions 3/3
73.8% Lines 31/42

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 11827x 27x 27x 27x         27x 27x     23x               16x 16x 16x                 16x 16x                   16x   16x             16x   5x   11x           11x 11x                           7x 7x 7x 7x 7x         7x 7x   7x       7x                       7x 7x 7x                      
export { IPFS };
import axios from "axios";
import FormData from "form-data";
import { makeString } from "../mina";
import { NAMES_ORACLE } from "..";
 
class IPFS {
  private auth: string;
  static ipfsData: { [key: string]: string } = {};
  static useLocalIpfsData: boolean = false as boolean;
 
  constructor(token: string) {
    this.auth = token;
  }
 
  public async pinJSON(params: {
    data: any;
    name: string;
    keyvalues?: object;
  }): Promise<string | undefined> {
    const { data, name, keyvalues } = params;
    console.log("saveToIPFS:", { name, keyvalues });
    Iif (this.auth === "local") {
      const hash = makeString(
        `bafkreibwikqybinoumbe6v2mpzwgluhqw7n4h6d5y7eq2nogils6ibflbi`.length
      );
      IPFS.ipfsData[hash] = data;
      IPFS.useLocalIpfsData = true;
      return hash;
    }
 
    try {
      const pinataData = {
        pinataOptions: {
          cidVersion: 1,
        },
        pinataMetadata: {
          name,
          keyvalues,
        },
        pinataContent: data,
      };
      const str = JSON.stringify(pinataData);
 
      const config = {
        headers: {
          "Content-Type": "application/json",
          Authorization: "Bearer " + this.auth,
        },
      };
 
      if (this.auth === "")
        //for running tests
        return `bafkreibwikqybinoumbe6v2mpzwgluhqw7n4h6d5y7eq2nogils6ibflbi`;
 
      const res = await axios.post(
        "https://api.pinata.cloud/pinning/pinJSONToIPFS",
        str,
        config
      );
 
      console.log("saveToIPFS result:", res.data);
      return res.data.IpfsHash;
    } catch (error: any) {
      console.error("saveToIPFS error:", error?.message);
      return undefined;
    }
  }
 
  public async pinFile(params: {
    stream: NodeJS.ReadableStream;
    name: string;
    size: number;
    mimeType: string;
    keyvalues?: object;
  }): Promise<string | undefined> {
    const { stream, name, size, mimeType, keyvalues } = params;
    console.log("pinFile:", { name, size, mimeType, keyvalues });
    try {
      const form = new FormData();
      form.append("file", stream, {
        contentType: mimeType,
        knownLength: size,
        filename: name,
      });
      form.append("pinataMetadata", JSON.stringify({ name, keyvalues }));
      form.append("pinataOptions", JSON.stringify({ cidVersion: 1 }));
 
      Iif (this.auth === "")
        //for running tests
        return `bafkreibwikqybinoumbe6v2mpzwgluhqw7n4h6d5y7eq2nogils6ibflbi`;
      // TODO: add retry logic
      const response = await axios.post(
        "https://api.pinata.cloud/pinning/pinFileToIPFS",
        form,
        {
          headers: {
            Authorization: "Bearer " + this.auth,
            "Content-Type": "multipart/form-data",
          },
          maxBodyLength: 25 * 1024 * 1024,
        }
      );
 
      console.log("pinFile result:", response.data);
      if (response && response.data && response.data.IpfsHash) {
        return response.data.IpfsHash;
      } else E{
        console.error("pinFile error", response.data.error);
        return undefined;
      }
    } catch (err) {
      console.error("pinFile error 2 - catch", err);
      return undefined;
    }
  }
}