¿Cómo agregar un archivo a IPFS usando la API?

He probado algunas API de IPFS como cat, ls. Pero no puedo agregar el archivo usando API. Como no existe la documentación adecuada de las llamadas a la API de IPFS.

¿Cómo puedo agregar un archivo en IPFS usando API?

FYI, discusión fuera de tema de esta pregunta en meta .
Cualquier ayuda será apreciada.
tengo el mismo problema, alguien lo soluciono?

Respuestas (4)

Lea la documentación :

Todos los comandos utilizables desde la cli también están disponibles a través de la API HTTP. Por ejemplo:

compañeros de enjambre de ipfs

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

Así que para el comando:

USO ipfs add... - Agrega un archivo a ipfs.

ARGUMENTOS

<ruta>...: la ruta a un archivo que se agregará a IPFS.

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

la llamada a la API equivalente sería:

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

Si desea utilizar una página web para cargar un documento en ipfs, debería ser algo como

<form action="http://127.0.0.1:5001/api/v0/add">
  <input type="file" name="image" accept="image/*">
  <input type="submit">
</form>
Quiero cargar un archivo desde la página html a ipfs usando ipfs api. Por favor guíame desde ese punto de vista. @Roland
Aniket lo agregó.
Muchas gracias. Me aseguraré de que sea correcto después de implementarlo. :)
Se requiere el argumento del archivo 'ruta' para obtener este error después de ejecutar su código html @Roland, la URL es como api/v0/add?image=imagename.jpg
¿Has intentado cambiar el nombre = "imagen" a "ruta"?
sí, lo intenté Ahora todavía muestra el mismo error con el reemplazo de 'ruta' a 'imagen' en url
Incluso arriba, dada la API equivalente (curl -F ...) tampoco funciona con la terminal. @Roland
esta cosa de la bandera de progreso podría ser la causa: stackoverflow.com/questions/37580093/ipfs-add-returns-2-jsons
mientras ejecuto ese comando api, solo me muestra un error que no puede encontrar ese archivo... y he agregado ese mismo archivo usando el comando normal @Roland

Agregar una nueva respuesta ya que no está relacionada con la anterior.

Muchas gracias a Vaibhav Saini que me apoyó en GitHub y en el foro de IPFS .

Es relativamente simple, por supuesto, puede simplificar aún más eliminando jQuery, que aquí se usa solo como on change input type filecontrolador:

<!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>

Prueba este: 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>
    );
  }
}

Código de: https://github.com/cluster-labs/ipfscloud-web#how-to-use

Prueba de que funcionó una vez: https://gateway.ipfs.io/ipfs/QmXhpBNwxEuXuuyKEpYouNvSZw2MqRemtUNSWKbKEiuhBv

Pero no puedo dar fe de ello al 100%.

(crédito por la simplicidad)

<!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>

EDITAR: está funcionando ahora, vea este problema

Agregué un nuevo nodo dedicado para ipfscloud. Ahora puedes confiar en él ;)
@VaibhavSaini gracias por toda la ayuda y el apoyo. La confianza (y la confiabilidad) es algo que construyes durante años, y luego un momento desaparece. Para mis necesidades, probablemente usaré Infura (respaldado por Consensys). Tienen recursos ilimitados. Entre otras noticias, felices de trabajar juntos, tienen mucho potencial 🔥🔥🔥