11

I have tried some APIs of IPFS like cat, ls. But I am not able to add the file using API. As there is no proper documentation of IPFS API calls.

How can I add a file on IPFS using API?

  • 1
    FYI, Off-topic discussion of this question at meta. – Waqar Lim Jun 3 '16 at 8:16
  • Any help will be appreciated. – BlockA Jun 7 '16 at 6:22
  • i'm having the same issue, someone solved? – user8244 May 9 '17 at 16:03
12

Read the documentation:

Every command usable from the cli is also available through the HTTP API. For example:

ipfs swarm peers

curl http://127.0.0.1:5001/api/v0/swarm/peers

So for the command:

USAGE ipfs add ... - Add a file to ipfs.

ARGUMENTS

< path >... - The path to a file to be added to IPFS.

https://ipfs.io/docs/commands/#ipfs-add

the equivalent API call would be:

curl -F "image=@/home/bar.jpg" 127.0.0.1:5001/api/v0/add

If you want to use a webpage to upload a document into ipfs it should be something like

<form action="http://127.0.0.1:5001/api/v0/add">
  <input type="file" name="image" accept="image/*">
  <input type="submit">
</form>
  • I want to upload a file from html page to ipfs using ipfs api. Please guide me from that point of view. @Roland – BlockA Jun 2 '16 at 10:21
  • aniket added it. – Roland Kofler Jun 2 '16 at 10:34
  • Thanks a lot. I'll make sure its correctness after implementing it. :) – BlockA Jun 2 '16 at 11:14
  • File argument 'path' is required getting this error after executing your html code @Roland, URL is like api/v0/add?image=imagename.jpg – BlockA Jun 3 '16 at 6:46
  • Have you tried to change name="image" to "path"? – Roland Kofler Jun 3 '16 at 6:48
1

Try this one: https://github.com/linonetwo/ipfs-uploader-browser

export default class FileUploadInput extends Component {
  static propTypes = {
    readAs: PropTypes.oneOf(['readAsDataURL', 'readAsArrayBuffer', 'readAsBinaryString', 'readAsText']),
    onReadSuccess: PropTypes.func.isRequired,
    onReadFailure: PropTypes.func.isRequired,
    allowMultiple: PropTypes.bool,
    validateFiles: PropTypes.func,
    initialText: PropTypes.string,
    inputProps: PropTypes.object,
    fileInputProps: PropTypes.object,
  };

  static defaultProps = {
    readAs: 'readAsArrayBuffer',
    allowMultiple: false,
    validateFiles: files => null,
    initialText: '',
    inputProps: {},
    fileInputProps: {},
  };

  node: any;
  stream: any;

  state = {
    progress: 0,
    totalFileSize: 0,
  };

  constructor(props) {
    super(props);
    this.state = { text: props.initialText, files: [] };

    // use random repo to initialize ipfs
    const repoPath = 'ipfs-' + Math.random();
    this.node = new IPFS({ repo: repoPath });

    // 'ready' will trigger after ipfs has start connecting to other peer
    this.node.on('ready', () => console.log('Online status: ', this.node.isOnline() ? 'online' : 'offline'));
  }

  /** 3.put file into IPFS */
  uploadIPFS = (fileArrayBuffer: ArrayBuffer): Promise<Buffer> => {
    return new Promise((resolve, reject) => {
      // set progress
      this.setState({ progress: 0 });
      // create stream that used to change progress
      const myReadableStreamBuffer = new streamBuffers.ReadableStreamBuffer({
        chunkSize: 25000,
      });
      // set progress
      myReadableStreamBuffer.on('data', (chunk: Buffer) => {
        this.setState({ progress: this.state.progress + chunk.byteLength });
        myReadableStreamBuffer.resume();
      });


      this.stream = this.node.files.addReadableStream();
      // resolve after file has uploaded
      this.stream.on('data', (file: Buffer) => resolve(file));

      // put file stream into IPFS's stream
      this.stream.write(myReadableStreamBuffer);
      myReadableStreamBuffer.put(Buffer.from(fileArrayBuffer));

      // close it after uploading
      myReadableStreamBuffer.on('end', () => this.stream.end());
      myReadableStreamBuffer.stop();
    });
  };

  /** 2.prepare file for IPFS uploading */
  readFile(file) {
    return new Promise((resolve, reject) => {
      const fileReader = new FileReader();
      fileReader.onload = event => resolve(this.uploadIPFS(event.target.result));
      fileReader.onerror = reject;
      fileReader[this.props.readAs](file);
    });
  }

  /** clear display */
  resetState() {
    this.setState({ text: '', files: [] });
  }

  /** 1.get file from <input/> */
  async handleChange(event: SyntheticInputEvent<EventTarget>) {
    // dealwith errors
    const files: File[] = Array.from(event.target.files);
    if (!files.length) {
      return this.resetState();
    }
    const errMsg = this.props.validateFiles(files);
    if (errMsg) {
      this.resetState();
      return this.props.onReadFailure(errMsg);
    }

    // update display
    const text = files.length > 1 ? `${files.length} files...` : files[0].name;
    this.setState({ text, files });

    // set progress's total size
    let totalFileSize = 0;
    files.forEach(file => {
      totalFileSize += file.size;
    });
    this.setState({ totalFileSize });
    // put file
    try {
      const response = await Promise.all([...files.map(aFile => this.readFile(aFile))]);
      this.props.onReadSuccess(response);
    } catch (err) {
      this.resetState();
      this.props.onReadFailure(err.message);
    }
  }

  render() {
    return (
      <span className={this.props.className}>
        {/* input used for display */}
        <input
          placeholder={this.props.allowMultiple ? 'Select files' : 'Select a file'}
          value={this.state.text}
          readOnly
          onClick={() => this.fileInput.click()}
          {...this.props.inputProps}
        />
        {/* input used for upload */}
        <input
          style={{ display: 'none' }}
          ref={el => (this.fileInput = el)}
          type="file"
          multiple={this.props.allowMultiple}
          onChange={e => this.handleChange(e)}
          {...this.props.fileInputProps}
        />
        <ProgressBar progress={this.state.progress} total={this.state.totalFileSize} />
      </span>
    );
  }
}
1

Adding a new answer as it is rather unrelated from the previous one.

Massive thanks to Vaibhav Saini who was supporting me on GitHub and IPFS forum.

It's relatively simple, of course you can simplify even further by removing jQuery, here used only as on change input type file handler:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Infura IPFS CORS issue</title>

    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.js"></script>
    <script src="https://unpkg.com/ipfs-http-client@30.1.3/dist/index.js"></script>
    <script src="https://bundle.run/buffer@5.2.1"></script>
  </head>
  <body>

    <h3>readAsArrayBuffer to Buffer to Infura to IPFS</h3>

    <input type="file" id="upload">

    <div id="link"></div> <!-- markup created after upload -->

    <script>
        const ipfs = window.IpfsHttpClient('ipfs.infura.io', '5001', { protocol: 'https' });

        $("#upload").on("change", function() {
            var reader = new FileReader();
            reader.onload = function (e) {

                const magic_array_buffer_converted_to_buffer = buffer.Buffer(reader.result); // honestly as a web developer I do not fully appreciate the difference between buffer and arrayBuffer 
                ipfs.add(magic_array_buffer_converted_to_buffer, (err, result) => {
                    console.log(err, result);

              let ipfsLink = "<a href='https://gateway.ipfs.io/ipfs/" + result[0].hash + "'>gateway.ipfs.io/ipfs/" + result[0].hash + "</a>";
              document.getElementById("link").innerHTML = ipfsLink;

                })
            }
            reader.readAsArrayBuffer(this.files[0]);
        })
    </script>

  </body>
</html>
0

Code from: https://github.com/cluster-labs/ipfscloud-web#how-to-use

Proof that it was working once: https://gateway.ipfs.io/ipfs/QmXhpBNwxEuXuuyKEpYouNvSZw2MqRemtUNSWKbKEiuhBv

But cannot 100% reliably vouch for it.

(credit for simplicity)

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>IpfsCloud demo</title>

    <link href="https://cdn.jsdelivr.net/gh/vasa-develop/ipfscloud@f157536445863f27481d8ce5e3025f25264d1113/app/docs/v1/css/ipfscloud-uploader.min.css" rel="stylesheet">

  </head>
  <body>

    <center>
        <div id="IpfsCloudUploader"></div>
        <div id="IpfsGatewayUploadedLink"></div>
    </center>

    <script src="https://code.jquery.com/jquery-3.3.1.min.js" integrity="sha256-FgpCb/KJQlLNfOu91ta32o/NMZxltwRo8QtmkMRdAu8=" crossorigin="anonymous"></script>
    <script src="https://cdn.jsdelivr.net/gh/vasa-develop/ipfscloud@bd23078768a5c708fc0f322a3e0e0cfb45b61f71/app/docs/v1/js/ipfscloud-uploader.min.js" ></script>

    <script>
    ipfscloud.addEventListener("icevent", function(event) {

        console.log(event.detail);

        if (event.detail.status === "success") {
            let ipfsLink = "https://gateway.ipfs.io/ipfs/" + event.detail.data.path;
            document.getElementById("IpfsGatewayUploadedLink").innerHTML = ipfsLink;

        } else {
            console.log(event.detail);
            alert("something happened, check console");
        }
    });
    </script>

  </body>
</html>

EDIT: it is workign now, see this issue

  • I added a new dedicated node for ipfscloud. Now you can rely on it ;) – Vaibhav Saini Apr 26 at 15:35
  • @VaibhavSaini thank you for all the help and support. Trust (and reliability) is something you build for years, and then one moment is gone. For my needs I'll probably use Infura (backed by Consensys). They have unlimited resources. Among other news - happy to work together, you have loads of potential 🔥🔥🔥 – Mars Robertson Apr 26 at 16:53

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.