From c4c343f179eb52c19af02c21908ee3c474faef0d Mon Sep 17 00:00:00 2001 From: ElPaisano <113373882+ElPaisano@users.noreply.github.com> Date: Mon, 24 Jul 2023 17:05:38 -0700 Subject: [PATCH] Update Helia and js-ipfs information / patch build (#1639) Co-authored-by: Russell Dempsey <1173416+SgtPooki@users.noreply.github.com> --- CONTRIBUTING.md | 4 +- README.md | 15 +- docs/.vuepress/config.js | 7 +- docs/.vuepress/redirects | 1 + docs/community/README.md | 2 +- docs/concepts/faq.md | 16 +- docs/concepts/glossary.md | 2 +- docs/concepts/ipns.md | 2 +- docs/concepts/nodes.md | 2 +- docs/how-to/companion-node-types.md | 2 - docs/how-to/configure-node.md | 5 +- docs/how-to/publish-ipns.md | 6 +- docs/install/README.md | 4 + docs/install/ipfs-companion.md | 2 +- docs/install/js-ipfs.md | 452 ---------------------------- 15 files changed, 52 insertions(+), 470 deletions(-) delete mode 100644 docs/install/js-ipfs.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3e436297f..87832cdaf 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -64,9 +64,9 @@ Write everything using the [GitHub Flavored Markdown](https://github.github.com/ ### Project-specific titles -When referring to projects by name, use proper noun capitalization: Kubo (GO-IPFS) and JS-IPFS. +When referring to projects by name, use proper noun capitalization. For example, Kubo and Helia. -Cases inside code blocks refer to commands and are not capitalized: `kubo` (`go-ipfs`) or `js-ipfs`. +Cases inside code blocks refer to commands and are not capitalized: `kubo` or `helia`. ### Style and tone diff --git a/README.md b/README.md index aca558e64..85a1b2c93 100644 --- a/README.md +++ b/README.md @@ -48,22 +48,27 @@ To build the site locally, follow the steps below. git clone https://github.com/ipfs/ipfs-docs.git ``` -2. Move into the `ipfs-docs` folder and install the NPM dependencies: +1. Move into the `ipfs-docs` folder: ```bash cd ipfs-docs + ``` + +1. Install the NPM dependencies: + + ```bash npm install ``` -3. Boot up the application in _dev mode_: +1. Boot up the application in _dev mode_: ```bash npm start ``` -4. Open [localhost:8080](http://localhost:8080) in your browser. -5. Close the local server with `CTRL` + `c`. -6. To restart the local server, run `npm start` from within the `ipfs-docs` folder. +1. Open [localhost:8080](http://localhost:8080) in your browser. +1. Close the local server with `CTRL` + `c`. +1. To restart the local server, run `npm start` from within the `ipfs-docs` folder. ### Troubleshooting diff --git a/docs/.vuepress/config.js b/docs/.vuepress/config.js index 3574e9138..c97730709 100644 --- a/docs/.vuepress/config.js +++ b/docs/.vuepress/config.js @@ -7,7 +7,7 @@ const pageSuffix = '/' const installMenuChildren = [ ['/install/command-line','IPFS Kubo for Go'], ['/install/run-ipfs-inside-docker', 'IPFS Kubo in Docker'], - ['/install/js-ipfs','IPFS for JavaScript'], + ['https://github.com/ipfs/helia','IPFS Helia for JavaScript'], ['https://iroh.computer/docs/install/', "IPFS Iroh for Rust"], ['/install/ipfs-desktop', 'IPFS Desktop App'], ['/install/ipfs-companion', 'IPFS Companion Browser Extension'], @@ -15,6 +15,11 @@ const installMenuChildren = [ ] module.exports = { + configureWebpack: { + output: { + hashFunction: "sha256" + } + }, base: '/', head: require('./head'), locales: { diff --git a/docs/.vuepress/redirects b/docs/.vuepress/redirects index 777c056b5..e2954dfd7 100644 --- a/docs/.vuepress/redirects +++ b/docs/.vuepress/redirects @@ -43,6 +43,7 @@ /how-to/troubleshoot-file-transfers /how-to/troubleshooting /how-to/run-ipfs-inside-docker /install/run-ipfs-inside-docker /install/command-line-quick-start/ /how-to/command-line-quick-start +/install/js-ipfs/ https://github.com/ipfs/helia/wiki /introduction/ /concepts /introduction/faq/ /concepts/faq /introduction/how-ipfs-works/ /concepts/how-ipfs-works diff --git a/docs/community/README.md b/docs/community/README.md index e0dae0992..8068ce704 100644 --- a/docs/community/README.md +++ b/docs/community/README.md @@ -60,7 +60,7 @@ Keeping in mind [the general guidelines above](#_2-follow-the-guidelines-for-get 1. In [the Help category of the forum](https://discuss.ipfs.tech/c/help/13), hover over the large blue circle with a `+` symbol in the center. The text **New Topic** displays. 1. Click **New Topic**. The **Create a new Topic** modal opens. 1. In the title field, describe what the discussion is one brief sentence. -1. Add any optional tags that help describe what subcategory the issue is in. Samples options include `go-ipfs` and `js-ipfs`. +1. Add any optional tags that help describe what subcategory the issue is in. Samples options include `kubo` and `helia`. 1. Following the guidelines above, describe your issue / problem in the main text field. You can use Markdown, BBCode or HTML for formatting, and include images. 1. Click **Create Topic**. Your topic is has been created in the forum! diff --git a/docs/concepts/faq.md b/docs/concepts/faq.md index 1bbce1ab9..79c62ae50 100644 --- a/docs/concepts/faq.md +++ b/docs/concepts/faq.md @@ -26,6 +26,10 @@ The quickest way to get IPFS up and running on your machine is by installing [IP For installing and initializing IPFS from the command line, check out the [command-line quick start](../how-to/command-line-quick-start.md) guide. +### How do I learn more about IPFS standards and specifications? + +You can learn more about IPFS design standards and architectural specifications at [specs.ipfs.tech](https://specs.ipfs.tech/). The IPFS Standards website documents these standards and specifications with the goal of fostering interoperability between independent implementations of the IPFS stack through Internet-grade specifications and test suites. + ### Why doesn't my SHA hash match my CID? When you add a file to IPFS, IPFS splits it into smaller blocks. IPFS hashes each of these pieces individually, building a [Merkle Directed Acyclic Graphs (DAGs)](../concepts/merkle-dag.md) and resulting in an overall different hash. @@ -45,10 +49,20 @@ An IPFS implementation is any software with basic functionality for interaction - Verifies that the CIDs it resolves match the resources they address, at least when it has access to the resources bytes. However, implementations may relax this requirement in controlled environments in which it is possible to ascertain that verification has happened elsewhere in a trusted part of the system. -There are already many IPFS implementations, including [Kubo](../install/command-line.md), [Helia](../install/js-ipfs.md), and [more](../concepts/ipfs-implementations.md). +There are already many IPFS implementations, including [Kubo](../install/command-line.md), [Helia](https://github.com/ipfs/helia), and [more](../concepts/ipfs-implementations.md). You can also create your own IPFS implementation. +### I am creating an implementation, how do I get started? + +If you want to develop an IPFS implementation or are already working on one, the IPFS design standards and architectural specifications at [specs.ipfs.tech](https://specs.ipfs.tech/) are a great resource. In particular, the following resources are great starting points: + +- [IPFS Principles](https://specs.ipfs.tech/architecture/principles/) provides context and details around the core IPFS principles of content-addressing and transport-agnosticism. The document defines what is or is not an IPFS implementation. +- The [Meta](https://specs.ipfs.tech/meta/) section describes important non-technical information for contributors, like the core project values, the governance model, how to produce documents, and more. +- [InterPlanetary Improvement Proposals (IPIPs)](https://specs.ipfs.tech/meta/ipip-process/) are a focused, transparent, community-driven process for protocol design discussions. They are not changes to the specification itself, but their approval leads to a change in the specification. + +In addition to these core documents, `specs.ipfs.tech` documents standards for IPFS subsystems such as the [InterPlanetary Naming System](https://specs.ipfs.tech/http-gateways/) and [HTTP Gateways](https://specs.ipfs.tech/http-gateways/). + ## IPFS and Filecoin ### What is the connection between IPFS and Filecoin? diff --git a/docs/concepts/glossary.md b/docs/concepts/glossary.md index 43287db46..c8bdbca5b 100644 --- a/docs/concepts/glossary.md +++ b/docs/concepts/glossary.md @@ -230,7 +230,7 @@ A Cryptographic Hash is a function that takes some arbitrary input (content) and ### Helia -A lean, modular, and modern implementation of IPFS for the JS and browser environments. Superseded [js-ipfs](#js-ipfs). Learn more at [https://github.com/ipfs/helia](https://github.com/ipfs/helia). +A lean, modular, and modern implementation of IPFS for the JS and browser environments that supersedes [js-ipfs](#js-ipfs). Learn more at [https://github.com/ipfs/helia](https://github.com/ipfs/helia). ### Hole punching diff --git a/docs/concepts/ipns.md b/docs/concepts/ipns.md index 426ffb368..825b49745 100644 --- a/docs/concepts/ipns.md +++ b/docs/concepts/ipns.md @@ -197,7 +197,7 @@ IPNS names can be resolved by [IPFS gateways](ipfs-gateway.md) in a _trusted_ fa ### Publishing IPNS names -See the following guide on [publishing IPNS names with Kubo and js-ipfs](../how-to/publish-ipns.md). +See the following guide on [publishing IPNS names with Kubo and Helia](../how-to/publish-ipns.md). ## Alternatives to IPNS diff --git a/docs/concepts/nodes.md b/docs/concepts/nodes.md index 4d998a533..c434df7c3 100644 --- a/docs/concepts/nodes.md +++ b/docs/concepts/nodes.md @@ -63,7 +63,7 @@ Both Kubo and Helia _nodes_ use bootstrap _nodes_ to initially enter the DHT. #### Limitations of a bootstrap node: - If an IPFS _node_ only has one bootstrap _node_ listed in that configuration and that bootstrap node goes offline, the IPFS node will lose access to the public DHT if it were to restart. - - Note that you should be able to configure your _peer_ store in your implementation to cache healthy connectable _peers_ so you can connect to them again after a restart, instead of bootstrap _nodes_. [Kubo recently added support for this](https://github.com/ipfs/kubo/pull/8856). +- You can configure your _peer_ store in your implementation to cache healthy connectable _peers_ so that you can connect to them again after a restart, instead of bootstrap _nodes_. [Issue 8856 in the Kubo repository](https://github.com/ipfs/kubo/pull/8856), which addressed this, provides further information and context. [More about Bootstrapping](../how-to/modify-bootstrap-list.md) diff --git a/docs/how-to/companion-node-types.md b/docs/how-to/companion-node-types.md index 26224383a..31b0cafbb 100644 --- a/docs/how-to/companion-node-types.md +++ b/docs/how-to/companion-node-types.md @@ -9,8 +9,6 @@ IPFS Companion's preferences screen allows you to choose from different node typ [[toc]] -![Screenshot of node type selector in Companion preferences](./images/node-type-switch.png) - **If you're already running a local IPFS node, choose _External_.** If not, do one of the following: - [Install](../install/README.md) and run IPFS as an [external node](#external) (recommended). diff --git a/docs/how-to/configure-node.md b/docs/how-to/configure-node.md index 8153d1647..681970f5b 100644 --- a/docs/how-to/configure-node.md +++ b/docs/how-to/configure-node.md @@ -5,5 +5,8 @@ description: IPFS nodes can be customzied using the configuration file. The defa # Configure a node -IPFS is configured through a json formatted text file, located by default at `~/.ipfs/config`. Implementation-specific information can be found within the [Kubo](https://github.com/ipfs/kubo/blob/master/docs/config.md) and [js-ipfs](https://github.com/ipfs/js-ipfs/blob/master/docs/CONFIG.md) repositories. It is read once at node instantiation, either for an offline command, or when starting the daemon. Commands that execute on a running daemon do not read the config file at runtime. +Node configuration varies between implementations. + +- For Kubo, see [config.md](https://github.com/ipfs/kubo/blob/master/docs/config.md). +- For Helia, see the [HeliaInit](https://ipfs.github.io/helia/interfaces/helia.HeliaInit.html) document. Note that, unlike the deprecated js-ipfs implementation, you must configure your node directly - see the [Helia example](https://github.com/ipfs/helia/wiki/Migrating-from-js-IPFS#config). diff --git a/docs/how-to/publish-ipns.md b/docs/how-to/publish-ipns.md index 6a75160d6..dbee60cc6 100644 --- a/docs/how-to/publish-ipns.md +++ b/docs/how-to/publish-ipns.md @@ -7,7 +7,8 @@ description: Learn how to publish IPNS names with Kubo IPNS names can be published programmatically. -- [Publishing IPNS names with Kubo](#publishing-ipns-names-with-kubo) +- [Using Kubo (Go)](#publishing-ipns-names-with-kubo) +- [Using helia-ipns (JavaScript)](#publishing-ipns-names-with-helia-ipns) ## Publishing IPNS names with Kubo @@ -101,3 +102,6 @@ ipfs name publish --key=SecondKey /ipfs/bafybeicklkqcnlvtiscr2hzkubjwnwjinvskffn > Published to k51qzi5uqu5dh5kbbff1ucw3ksphpy3vxx4en4dbtfh90pvw4mzd8nfm5r5fnl: /ipfs/bafybeicklkqcnlvtiscr2hzkubjwnwjinvskffn4xorqeduft3wq7vm5u4 ``` +## Publishing IPNS names with helia-ipns + +Learn more about using IPNS with JavaScript at the [helia-ipns](https://github.com/ipfs/helia-ipns) repository. \ No newline at end of file diff --git a/docs/install/README.md b/docs/install/README.md index c4daa37a7..dcaaaf8f0 100644 --- a/docs/install/README.md +++ b/docs/install/README.md @@ -21,6 +21,10 @@ For long-term storage, users can use the Filecoin network! Filecoin is a peer-to Want to build decentralized applications and store your application data on IPFS? You'll likely want to install the command-line version of IPFS. There's no GUI to deal with, just raw input and output through your terminal. [Find out more →](./command-line.md) +## IPFS Helia + +[Helia](https://github.com/ipfs/helia) is a new implementation of IPFS in JavaScript that is designed to be more modular and lightweight than the deprecated [js-ipfs project](https://github.com/ipfs/js-ipfs). To get started with a hands-on example, see [Helia 101](https://github.com/ipfs-examples/helia-examples/blob/main/examples/helia-101/README.md) in [ipfs-examples/helia-examples](https://github.com/ipfs-examples/helia-examples/tree/main). + ## IPFS Cluster Planning to set up several IPFS nodes within one network? You'll want to take a look at installing [IPFS Cluster →](./server-infrastructure.md) diff --git a/docs/install/ipfs-companion.md b/docs/install/ipfs-companion.md index 912141f46..f4829dbdd 100644 --- a/docs/install/ipfs-companion.md +++ b/docs/install/ipfs-companion.md @@ -13,7 +13,7 @@ For its full functionality to be enabled, IPFS Companion requires a local IPFS n - [Install IPFS Desktop](../install/ipfs-desktop.md) - [Install IPFS Kubo for Go](../install/command-line.md) -- [Install IPFS for JavaScript](../install/js-ipfs.md) +- [Install IPFS Helia for JavaScript](https://github.com/ipfs/helia) ## Install diff --git a/docs/install/js-ipfs.md b/docs/install/js-ipfs.md deleted file mode 100644 index 8679ea9d1..000000000 --- a/docs/install/js-ipfs.md +++ /dev/null @@ -1,452 +0,0 @@ ---- -title: IPFS for JavaScript (js-ipfs) -description: "A simple walkthrough of how to perform basic IPFS operations using the JavaScript implementation." ---- - -# Install IPFS for JavaScript (js-ipfs) - -:::warning -### js-ipfs being discontinued -Development of the [js-ipfs project](https://github.com/ipfs/js-ipfs) is being discontinued to focus on [Helia](https://github.com/ipfs/helia), a leaner, more modular, modern implementation of IPFS in JavaScript scheduled for release in 2023. To learn more about Helia and the current state of IPFS in JS, see the [blog post](https://blog.ipfs.tech/state-of-ipfs-in-js/). - -Because of this, js-ipfs tutorials may be out of date, and will eventually be archived. - -::: - -This guide will walk you through the basics of using JS-IPFS, an implementation of IPFS in JavaScript. JS-IPFS is one of multiple [IPFS implementations](../concepts/ipfs-implementations.md). You will learn how to install and spawn a node using the available libraries, and add, retrieve, read, and remove files. If you are unsure about the meaning of some terms, check out the [glossary](../concepts/glossary.md). - -::: tip Environment - -All instructions and examples shown here were performed and tested on an M1 Mac. However, the IPFS commands are the same on Linux, macOS, and Windows. You will to navigate your computer's directories from within the CLI. If you're unsure how to use the CLI, we recommend learning how before continuing with this guide. - -::: - -There are two ways to work with IPFS using JavaScript; the [JS-IPFS](../reference/js/api.md#js-ipfs) library or the [HTTP client](../reference/js/api.md#http-client). We'll show you how to use both in this guide. - -## Install JS-IPFS - -:::: tabs - -::: tab ipfs-cli id="install-ipfs-cli" - -### JS-IPFS module - -To use the CLI on your machine, globally install the `ipfs` Node.js package: - - ```bash - npm i --location=global ipfs - ``` - -Alternatively, you can build the project from the source. See the [JS-IPFS GitHub repository](https://github.com/ipfs/js-ipfs) for instructions. - -::: - -::: tab ipfs-core id="install-ipfs-core" - -### IPFS core API - -To use the IPFS core API, install the `ipfs-core` Node.js package: - - ```bash - npm i ipfs-core - ``` - -Alternatively, you can build the project from the source. See the [JS-IPFS GitHub repository](https://github.com/ipfs/js-ipfs) for instructions. - -::: - -:::: - -## Spawn a node - -:::: tabs - -::: tab ipfs-cli id="spawn-ipfs-cli" - -1. To spawn a node using the CLI, start the daemon: - - ```bash - jsipfs daemon - ``` - -2. You should see an output similar to: - - ```shell - Initializing IPFS daemon... - System version: arm64/darwin - Node.js version: 16.16.0 - Swarm listening on /ip4/127.0.0.1/tcp/4002/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - Swarm listening on /ip4/10.0.0.25/tcp/4002/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - Swarm listening on /ip4/10.2.0.2/tcp/4002/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - Swarm listening on /ip4/127.0.0.1/tcp/4003/ws/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - js-ipfs version: 0.15.4 - HTTP API listening on /ip4/127.0.0.1/tcp/5002/http - gRPC listening on /ip4/127.0.0.1/tcp/5003/ws - Gateway (read only) listening on /ip4/127.0.0.1/tcp/9090/http - Web UI available at http://127.0.0.1:5002/webui - Daemon is ready - ``` - -3. You should be able to point to the [webpage](http://127.0.0.1:5002/webui) using the address output by the terminal `http://127.0.0.1:5002/webui`: - -4. If you are unable to connect to the API, ensure [cross-origin (CORS)](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) requests are configured: - - ```bash - jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["http://127.0.0.1:5002", "http://localhost:3000", "http://127.0.0.1:5001", "https://webui.ipfs.io"]' - jsipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "POST"]' - ``` - -::: - -::: tab ipfs-core id="spawn-ipfs-core" - -Create a simple Node.js application to host the logic that will allow you to use the RPC API. You'll also use this Node.js application later on to add and remove files. - -1. Start by initiating a new project: - - ```bash - npm init -y - ``` - -1. If you have not already installed `ipfs-core`, add the `ipfs-core` module to your project: - - ```bash - npm i ipfs-core - ``` - -1. Create an `index.js` file for the application logic: - - ```bash - touch index.js - ``` - -1. Now, populate the `index.js` file by initiating an `async` function: - - ```js - const main = async () => { - // "await" logic to spawn a node - } - - main() - ``` - -1. To create an IPFS node, add: - - ```js{1,4} - import * as IPFS from 'ipfs-core'; - - async function main() { - const node = await IPFS.create(); - } - - main(); - ``` - - This imports IPFS as a dependency and uses the `create()` function to create a node instance. - -1. To spawn the node, run the application: - - ```bash - node index.js - ``` - -1. You should see an output similar to: - - ```shell - Swarm listening on /ip4/127.0.0.1/tcp/4002/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - Swarm listening on /ip4/10.0.0.25/tcp/4002/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - Swarm listening on /ip4/127.0.0.1/tcp/4003/ws/p2p/12D3KooWMZr34r6FArFH36QxyT25BM4HL4u2WF7jQzwNdg91awB6 - ``` - -::: - -:::: - -### Connect to IPFS - -The JS-IPFS implementation is split into several Node.js modules. The following section shows examples of using the HTTP client to connect to IPFS. For more information on the different modules, examine the [API Packages table](../reference/js/api.md##packages) - -:::: tabs - -::: tab ipfs-http-client id="connect-ipfs-http-client" - -1. If you have not already installed the client library, add the `ipfs-http-client` module to your project: - - ```bash - npm i ipfs-http-client - ``` - -1. Populate your `index.js` file with the following to create an instance of the HTTP API client: - - ```js{1,3} - import { create } from 'ipfs-http-client' - - const client = create() // the default API address http://localhost:5001 - ``` - - This imports the client library and uses the `create()` function to connect to an IPFS API server. - -1. To connect to the API, run the application: - - ```bash - node index.js - ``` - -The library internally detects if your machine is running a local node. - -::: - -::: tab ipfs-client id="connect-ipfs-client" - -1. If you have not already installed the client library, add the `ipfs-client` module to your project: - - ```bash - npm i ipfs-client - ``` - -1. Populate your `index.js` file with the following to create an instance of the HTTP API client: - - ```js{1,3-5} - import { create } from 'ipfs-client' - - const client = create({ - grpc: '/ip4/127.0.0.1/tcp/5003/ws', - http: '/ip4/127.0.0.1/tcp/5002/http' - }) - - const id = await client.id() - ``` - - This imports the client library and uses the `create()` function to define the server endpoints. - -1. To connect to the endpoints, run the application: - - ```bash - node index.js - ``` - -The library internally detects if your machine is running a local node that leverages the specified connections. - -::: - -:::: - -## Add a file - -Now you can start to add files using JS-IPFS to the IPFS network. - -::: warning Section changes coming soon - -As the JS-IPFS implementation changes, some of these steps should be deemed conditional. Please reference the [source packages](https://github.com/ipfs/js-ipfs) for the latest updates. - -::: - -:::: tabs - -::: tab ipfs-cli id="add-ipfs-cli" - -1. In a new session, navigate to the directory from which you wish to add a file. You can also specify the file path when using the cli to add a file. -2. The daemon uses an `ADD` method to request data from IPFS; `jsipfs add`. We will use a test file called `test.txt` to add through the jsipfs daemon. - - ```bash - jsipfs add ./test.txt - ``` - -3. You should obtain a result that verifies the file was added and returns the CID: - - ```shell - added QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi test.txt - ``` - -4. The file has been added to the IPFS network and has given the file a CID. You can share this CID with anyone, and they can use it on their IPFS node to obtain the content you uploaded. -5. To view the file contents, navigate to the [webui](http://127.0.0.1:5002/webui) and provide the CID on the search bar. The UI will provide the file contents, similar to the following: - -::: - -::: tab ipfs-core id="add-ipfs-core" - -1. To add a file using `ipfs-core`, you can create a test `.txt` file in your project directory or point to a local file on your machine that you would like to upload to IPFS. -1. Then, using `node.add`, add an `await` operator that includes a `path` and `content` field and an output message in the project's `index.js` file: - - ```js{6-9,11} - import * as IPFS from 'ipfs-core'; - - async function main() { - const node = await IPFS.create(); - - const fileAdded = await node.add({ - path: "test.txt", - content: "Hello IPFS!", - }); - - console.log("Added file:", fileAdded.path, fileAdded.cid); - } - - main(); - ``` - -1. You should obtain an output similar to: - - ```shell - Added file: test.txt CID(QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk) - ``` - -1. The file has been added to the IPFS network and has given the file a CID. You can share this CID with anyone, and they can use it on their IPFS node to obtain the content you uploaded. -1. If you take the CID and load it on the HTTP gateway, you will see the content `https://ipfs.io/ipfs/QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk`: - -::: - -:::: - -## Retrieve a file - -::::tabs - -::: tab ipfs-cli id="retrieve-ipfs-cli" - -1. Navigate to the directory where you wish to save the folder. IPFS will save the folder to whichever directory you are in. Here, we're going to save the file in the ~/Desktop directory: - - ```bash - cd ~/Desktop - ``` - -1. We must specify the CID to the jsipfs daemon to retrieve our desired content. The daemon uses a `GET` method to request data from IPFS; `jsipfs get`. We will use the CID from the previous section where we added the `test.txt` file: - - ```bash - jsipfs get QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi - ``` - -1 You should see an output similar to: - - ```bash - Saving file(s) to QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi - ``` - -1. You will notice a new file in your project directory that is labeled as the CID of the retrieved content. - -::: - -::: tab ipfs-core id="retrieve-ipfs-core" - -1. Continuing with the same Node.js application, retrieving a file from IPFS can be done by using a `cat` call. We will use the CID from the previous section when we added the `test.txt` file by passing `fileAdded.cid` as an argument to `node.cat`. However, you can use the same setup to retrieve any file by defining the CID. - - ```js{13-16,18} - import * as IPFS from 'ipfs-core'; - - async function main() { - const node = await IPFS.create(); - - const fileAdded = await node.add({ - path: "hello.txt", - content: "Hello World 101", - }); - - console.log("Added file:", fileAdded.path, fileAdded.cid); - - const chunks = []; - for await (const chunk of node.cat(fileAdded.cid)) { - chunks.push(chunk); - } - - console.log("Retrieved file contents:", chunks.toString()); - } - - main(); - ``` - -1. You should retrieve the file contents: - - ```shell - Retrieved file contents: Hello IPFS! - ``` - -:::: - -### Pin a file - -Pinning a file will save the file data save to the local IPFS node and ensure data is not lost. - -1. Using the `pin add` method on the daemon, you can pin a file by running: - - ```bash - jsipfs pin add QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi - ``` - -1. The result should be something like: - - ```shell - pinned QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi - ``` - -By default, objects that you retrieve over IPFS are not pinned to your node. If you wish to prevent the files from being garbage collected, you need to pin them. You will notice that the pin you just added is a recursive pin, meaning it is a directory containing other objects. Check out the [pinning content](../concepts/persistence.md#pinning-in-context) to learn more about pinning. - -## Remove a file - -::: warning Removing a file from IPFS does not guarantee that it was completely removed from the network. - -There is no way to know if someone else has made a copy of the content from when it became available on the network. This caveat is also found in regular HTTP networks, as nothing stops users from addressing content and creating a copy once it is pushed to IPFS. - -::: - -Removing the content pin will remove a file from IPFS. In this section, we will remove the pinned `test.txt` file we pinned earlier. - -:::: tabs - -::: tab ipfs-cli id="remove-ipfs-cli" - -1. If you would like to remove a different piece of content, you can run `jsipfs pin ls` to view a list of pinned content on the local IPFS node: - - ```shell - QmRaaUwTNfwgFZpeUy8qrZwrp2dY4kCKmmB5xEqvH3vtD1 recursive - QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn recursive - QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi recursive - QmXgZAUWd8yo4tvjBETqzUy3wLx5YRzuDwUQnBwRGrAmAo recursive - QmYt9ypyGsR1BKdaCGPdwdBgAiuXK5AYN2bGSNZov7YXuk recursive - QmSVcZ3G5SFZMMk9egqHBaMch4aKYpaaCnxBAJCQR25Am4 indirect - QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y indirect - QmegvLXxpVKiZ4b57Xs1syfBVRd8CbucVHAp7KpLQdGieC indirect - QmQN88TEidd3RY2u3dpib49fERTDfKtDpvxnvczATNsfKT indirect - QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 indirect - QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha indirect - QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB indirect - QmQ5vhrL7uv6tuoN9KeVBwd4PwfQkXdVVmDLUZuTNxqgvm indirect - QmV4KrV1DBzTaA5xJWTYNx852YjRsrcTGGsaSR5a7gBzbr indirect - QmYE7xo6NxbHEVEHej1yzxijYaNY51BaeKxjXxn6Ssa6Bs indirect - ``` - -1. Using the daemon's `pin rm` method, unpin the file: - - ```bash - jsipfs pin rm QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi - ``` - -1. This will output something like: - - ```shell - unpinned QmWcYcWY5vdDzBcAoLo3rYXQ2tLkjzu57vEePCvyhuwZRi - ``` - -1. `test.txt` file is now unpinned, but it has not been removed from our node completely. To remove it completely, run the [garbage collection](../concepts/persistence.md#garbage-collection). The command will remove everything from your node that does not have a pin: - - ```shell - jsipfs repo gc - ``` - -1. This will output something like: - - ```shell - removed bafybeif2ewg3nqa33mjokpxii36jj2ywfqjpy3urdh7v6vqyfjoocvgy3a - removed bafkreieceevgg2auxo4u3rjgeiqfr4ccxh6ylkgxt2ss6k2leuad5xckxe - removed bafkreiblcvcr7letdbp2k2thkbjyunznrwq3y6pyoylzaq4epawqcca2my - [...] - ``` - -2. The target file has now been removed from your IPFS node and other files that were not pinned. If the content that was just garbage collected was saved to your computer's local storage, it is still there. If you wish to remove the content from your computer's local storage, you will need to find where it is saved and delete it using the normal deletion method. - -::: tip - -Run `jsipfs pin ls` again to confirm that the CID you intended to remove is no longer pinned. - -::: - -::::