Как добавить файл в IPFS с помощью API?

Я пробовал некоторые API-интерфейсы IPFS, такие как cat, ls. Но я не могу добавить файл с помощью API. Поскольку нет надлежащей документации вызовов API IPFS.

Как я могу добавить файл в IPFS с помощью API?

К вашему сведению, обсуждение этого вопроса не по теме на сайте meta .
Любая помощь будет оценена.
у меня такая же проблема, кто-то решил?

Ответы (4)

Прочтите документацию :

Каждая команда, которую можно использовать из cli, также доступна через HTTP API. Например:

роевые пиры ipfs

завиток http://127.0.0.1:5001/api/v0/swarm/peers

Итак, для команды:

ИСПОЛЬЗОВАНИЕ ipfs add... - Добавить файл в ipfs.

АРГУМЕНТЫ

<путь>... - Путь к файлу, который нужно добавить в IPFS.

https://ipfs.io/docs/commands/#ipfs-добавить

эквивалентный вызов API будет:

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

Если вы хотите использовать веб-страницу для загрузки документа в ipfs, это должно быть что-то вроде

<form action="http://127.0.0.1:5001/api/v0/add">
  <input type="file" name="image" accept="image/*">
  <input type="submit">
</form>
Я хочу загрузить файл с html-страницы в ipfs, используя ipfs api. Пожалуйста, направьте меня с этой точки зрения. @Роланд
Аникет добавил это.
Большое спасибо. Я удостоверюсь в его правильности после его реализации. :)
Аргумент файла «путь» требуется для получения этой ошибки после выполнения вашего html-кода @Roland, URL-адрес похож на api/v0/add?image=imagename.jpg
Вы пытались изменить имя = "изображение" на "путь"?
да, я пытался. Теперь он по-прежнему показывает ту же ошибку с заменой «пути» на «изображение» в URL-адресе.
Даже приведенный выше эквивалентный API (curl -F ...) также не работает с использованием терминала. @Роланд
причиной может быть этот флаг прогресса: stackoverflow.com/questions/37580093/ipfs-add-returns-2-jsons
при запуске этой команды API она просто показывает мне ошибку, что не может найти этот файл .... и я добавил тот же файл, используя обычную команду @Roland

Добавление нового ответа, поскольку он не имеет отношения к предыдущему.

Огромное спасибо Vaibhav Saini , который поддерживал меня на GitHub и форуме IPFS .

Это относительно просто, конечно, вы можете упростить еще больше, удалив jQuery, который здесь используется только как on change input type fileобработчик:

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

Попробуйте этот: 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>
    );
  }
}

Код из: https://github.com/cluster-labs/ipfscloud-web#how-to-use

Доказательство того, что это работало один раз: https://gateway.ipfs.io/ipfs/QmXhpBNwxEuXuuyKEpYouNvSZw2MqRemtUNSWKbKEiuhBv

Но не может 100% достоверно поручиться за это.

(кредит на простоту)

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

РЕДАКТИРОВАТЬ: теперь это работает, см. этот вопрос

Я добавил новый выделенный узел для ipfscloud. Теперь на него можно положиться ;)
@VaibhavSaini спасибо за всю помощь и поддержку. Доверие (и надежность) — это то, что вы строите годами, а потом один момент проходит. Для своих нужд я, вероятно, буду использовать Infura (при поддержке Consensys). У них неограниченные ресурсы. Среди прочих новостей - рады совместной работе, у вас огромный потенциал 🔥🔥🔥