Web 3 Tutorial - How to upload and serve files in IPFS network using NodeJs

Web3 is fascinating and uncharted territory. Recently, I decided to learn a few things about Web3 technologies. Even though I had some basic ideas about the blockchain and NFTs, I’ve never tried writing a program for Web3.

So I decided to learn about Web3 technology and write a simple program that can upload files to the IPFS network. 

What is IPFS?

Before getting started, if you don’t know what is IPFS, IPFS stands for InterPlanatry File System. It’s a protocol to save files in a decentralized netowork of computers. If you upload a file to Google Drive, you upload your file to a server belonging to Google. The server belongs to Google, and therfore it is a centralised storage. 

However, unlike Google Drive, the IPFS protocol strores files in computers around the world. There is no single owner to the network or the computers storing the data. Therefore it’s decentralised. It’s somewhat similar to the BitTorrent protocol used for file sharing. 

However, unlike Google Drive, the data you upload to IPFS is not private. Therefore, you should not upload or store sensitive data on the IPFS network. Also, once you upload data to the IPFS network, it remains forever on the IPFS network, and you can’t edit or delete your data. If you want to edit, you need to re upload a modified copy and use that instead. 

Because of this nature, IPFS network is used to save NFT images as well.

Now that you have a basic idea about the IPFS protocol. Let’s try to write a program using NodeJs to upload a file to the IPFS network. You will need to have some basic knowlage in JavaScript to understand the code. And you will need a text editor like VsCode.

Create a new NodeJs project

Create a new NodeJs project by running,

npm init -y

You will get a new project in your local computer.

Install the dependancies

npm install nft.storage node-fetch notenv

Obtain an NFT.storage API key

NFT.storage is a service (IPFS gateway) that makes it easy to upload and serve files over the IPFS network through their API, as they will to the heavy lifting.

You can also use the ipfs-js libraty to upload and serve files over IPFS protocol.

You can easily signup on nft.storage using your GitHub account and obtain an API key.

Save the API key you got from nft.storage in a .env file.

Uploading your file to IPFS

I’ve stored a simple png file as test.png in the project folder that we will upload to the IPFS netowrk.

We are using the following code to upload the file to the IPFS network. It’s simple and self explanatory. 

import { NFTStorage, File } from "nft.storage";
import fs from "fs";
import dotenv from "dotenv";
import fetch from "node-fetch";

dotenv.config();

const { NFT_STORE_API_KEY } = process.env;
const storeAsset = async () => {
  const client = new NFTStorage({ token: NFT_STORE_API_KEY });
  const metaData = await client.store({
    name: "Example NFT",
    description: "Testing IPFS network",
    image: new File([await fs.promises.readFile("test.png")], "test.png", {
      type: "image/png",
    }),
  });

  return metaData.url;
};

Apart from the image, we can also upload some metadata in JSON format associated with the file we upload to the IPFS network. In the example, we are adding a name and description as metadata. The link to the image file will be in the image property of the metadata. 

The function will return the ifps url of your uploaded file’s metadata.json file. The metadata.json file contains all the information about the file you just uploaded to the IPFS network (name, description, image etc).

The image property of the json will have the link to the image file you just uploaded.

ipfs://bafyreice4ib5is4zjv3kugad5rzlvgsojuq767qbys6ppwy5itys3gi2ze/metadata.json

Great, you successfully uploaded a file to the IPFS network, soon it will be in someone else’s storage forever.

Opening an IPFS file from the browser

Unlike a regular URL, you can’t directly open an ipfs url from your browser. You will need to use a gateway, such as CloudFlare IPFS gateway or ipfs.io.

You need to replace the protocol of your IPFS link (ipfs://) with https://ips.io or https://clourflare-ipfs.com and you will be able to read the contents of the metadata file.

The following code will replace the ipfs:// protocol of your IPFS url to a one that can be accessed via the CloudFlare IPFS gateway.

const ipfsToHttp = (url) => {
  return url.replace("ipfs://", "https://cloudflare-ipfs.com/ipfs/");
};

If you read the metadata.json file, the image property of the JSON file will contain the link to the image file you just uploaded.

We can use fetch to retrieve the metadata.json file.

const getMetaData = async (url) => {
  const metaData = fetch(url)
    .then((response) => response.json())
    .then((data) => {
      return data;
    });

  return metaData;
};

The output would be like this

{
    "name":"Example NFT",
    "description":"Testing storing",
    "image":"ipfs://bafybeid5klxzkhkc2qe36s2tqu5anysou3y5fpet2ovfihtr2l76hrnybu/test.jpeg"
}

Now all you need to do is convert the image property’s IPFS link to an http protocol link though the CloudFlare IPFS gateway and you will be able to access your image file that you just uploaded to the IPFS network.

https://cloudflare-ipfs.com/ipfs/bafybeid5klxzkhkc2qe36s2tqu5anysou3y5fpet2ovfihtr2l76hrnybu/test.jpeg

You can find the full code in the GitHub repo – https://github.com/rukshn/web3-lessons