Build a Web3 notes app in 4 steps?
In this article we will be creating a notes app using IPFS. IPFS is a decentralized storage.
To create this app we will be using following tools-
- zk-block - boilerplate for zk and web3 dapps. ( NextJS, React, Typescript, Metamask)
- web3 storage - library for IPFS and provides an easy and scalable way to store data on IPFS
We wont be diving into UI or ReactJs part of the app. As these are outside the scope of the article.
When dealing with any storage, there are mainly two tings that we need to deal with -
- Storing data
- Retrieving data
Assuming you can handle creating a UI and user inputs in react, we can just focus on the code that will help you interact with the IPFS using web3.storage
.
1. Install the web3.storage
npm install web3.storage
2. You need to get an access token
Getting an access token is free, and you can get yours at https://web3.storage/account/.
3. Create a storage client object
const storage = new Web3Storage({ token: process.env.NEXT_PUBLIC_WEB3_KEY });
4. Store & Retrieve Files
Storing
The Web3.Storage client's put
method accepts an array of File objects. So, we will have to convert any data that we want to store in a File
object.
const finalContent = JSON.stringify(content);
const file = new File([finalContent], await sha256(finalContent), {
type: 'text/plain',
});
Once, we have the File
object. we can simply call put
to store or upload the files to IPFS
const cid = await storage.put([file]);
CID you get back from the client when uploading is the CID of the directory and not the file itself.
To link to the file itself using an IPFS URI, just add the filename to the CID, separated by a /
like this: ipfs://<cid>/<filename>
.
For eg, to access this blog link stored on ipfs you can use the below link -
https://ipfs.io/ipfs/bafybeicbv3pjrmkx7vy27puybjitqibzo6r5hrlc2exp6jh4kf4ijhpaqe
Optional: put also provides callback functions to show upload progress.
const onRootCidReady = (cid) => {
console.log('uploading files with cid:', cid);
};
const onStoredChunk = (size) => {
uploaded += size;
const pct = totalSize / uploaded;
console.log(`Uploading... ${pct.toFixed(2)}% complete`);
};
await storage.put(files, { onRootCidReady, onStoredChunk });
Retrieving
You can retrieve your uploaded data by -
https://<cid>.ipfs.dweb.link/
https://ipfs.io/ipfs/<cid>
or via code
const web3ResponseObject = await storage.get(cid); // Web3Response object
The web3ResponseObject
extends the Response object from the Web Fetch API with two methods that provide access to the retrieved IPFS data: files
and unixFsIterator()
.
The files
method returns an array of Web3File
objects, which represent all files contained in the content archive identified by the given CID. A Web3File
is just like a regular web File
object, with the addition of path
and cid
properties. These contain the relative path of the file within the archive and the CID of the file, respectively.
const files = await web3ResponseObject.files(); // return your files
You can checkout the notes app in action here
Optional: Encrypting the data
Since, all the data is publicly accessible and sometimes its best to store data in encrypted form.
const stringifiedContent = JSON.stringify(content);
const finalContent = CryptoJS.AES.encrypt(
stringifiedContent,
password,
).toString();
and you can decrypt like below,
const retrievedContent = CryptoJS.AES.decrypt(reader.result, password).toString(
CryptoJS.enc.Utf8,
);
const actualContent = JSON.parse(retrievedContent);
That's all!