Explore the docs
·
View Demo
·
Report Bug
·
Request Feature/Example
- Table of Contents
- About The Project
- Getting Started
- Usage
- Documentation
- Contributing
- Want to hack on IPFS?
- Read the docs
- Look into other examples to learn how to spawn a Helia node in Node.js and in the Browser
- Visit https://dweb-primer.ipfs.io to learn about IPFS and the concepts that underpin it
- Head over to https://proto.school to take interactive tutorials that cover core IPFS APIs
- Check out https://docs.ipfs.io for tips, how-tos and more
- See https://blog.ipfs.io for news and more
- Need help? Please ask 'How do I?' questions on https://discuss.ipfs.io
Make sure you have installed all of the following prerequisites on your development machine:
- Git - Download & Install Git. OSX and Linux machines typically have this already installed.
- Node.js - Download & Install Node.js and the npm package manager.
> npm install
> npm start
In this tutorial, we go through spawning a Helia node, adding a file and cating the file CID locally and through the gateway.
It it split into three parts, each part builds on the previous one - basics, storage and finally networking.
For this tutorial, you need to install all dependencies in the package.json
using npm install
.
In the 101-basics.js example the first thing we do is create a Helia node:
import { createHelia } from 'helia'
// create a Helia node
const helia = await createHelia()
This node allows us to add blocks and later to retrieve them.
Next we use @helia/unixfs
to add some data to our node:
import { unixfs } from '@helia/unixfs'
// create a filesystem on top of Helia, in this case it's UnixFS
const fs = unixfs(helia)
// we will use this TextEncoder to turn strings into Uint8Arrays
const encoder = new TextEncoder()
const bytes = encoder.encode('Hello World 101')
// add the bytes to your node and receive a unique content identifier
const cid = await fs.addBytes(bytes)
console.log('Added file:', cid.toString())
The bytes
value we have passed to unixfs
has now been turned into a UnixFS DAG and stored in the helia node.
We can access it by using the cat
API and passing the CID that was returned from the invocation of addBytes
:
// this decoder will turn Uint8Arrays into strings
const decoder = new TextDecoder()
let text = ''
for await (const chunk of fs.cat(cid)) {
text += decoder.decode(chunk, {
stream: true
})
}
console.log('Added file contents:', text)
That's it! We've created a Helia node, added a file to it, and retrieved that file.
Next we will look at where the bytes that make up the file go.
Out of the box Helia will store all data in-memory. This makes it easy to get started, and to create short-lived nodes that do not persist state between restarts, but what if you want to store large amounts of data for long amounts of time?
Take a look at 201-storage.js where we explore how to configure different types of persistent storage for your Helia node.
At it's heart the Interplanetary Filesystem is about blocks. When you add a file to your local Helia node, it is split up into a number of blocks, all of which are stored in a blockstore.
Each block has a CID, an identifier that is unique to that block and can be used to request it from other nodes in the network.
A blockstore is a key/value store where the keys are CIDs and the values are Uint8Arrays.
By default we're going to use an in-memory blockstore, though later you may wish to use one that stores blocks on a filesystem.
import { MemoryBlockstore } from 'blockstore-core'
const blockstore = new MemoryBlockstore()
There are many blockstore implementations available. Some common ones are:
- blockstore-fs - store blocks in a directory on the filesystem using Node.js
- blockstore-idb - store blocks in IndexedDB in the browser
- blockstore-s3 - store blocks in an AWS S3 bucket
Some facility to store information is required, this needs a datastore.
Similar to the blockstore, a datastore is a key/value store where the keys are strings and the values are Uint8Arrays.
import { MemoryDatastore } from 'datastore-core'
const datastore = new MemoryDatastore()
Commonly used datastore implementations are:
- datastore-level - store key/value pairs in a LevelDB instance
- datastore-idb - store key/value pairs in IndexedDB in the browser
- blockstore-s3 - store key/value pairs in an AWS S3 bucket
The final example is 301-networking.js.
Adding blocks to your local blockstore is great but using your Helia node's libp2p instance allows you to unlock the full power of the distributed web.
With libp2p configured you can retrieve blocks from remote peers, and those peers can retrieve blocks from you.
libp2p is the networking layer that IPFS works on top of. It is a modular system, comprising of transports, connection encrypters, stream multiplexers, etc.
import { createLibp2p } from 'libp2p'
import { identifyService } from 'libp2p/identify'
import { noise } from '@chainsafe/libp2p-noise'
import { yamux } from '@chainsafe/libp2p-yamux'
import { webSockets } from '@libp2p/websockets'
import { bootstrap } from '@libp2p/bootstrap'
import { MemoryDatastore } from 'datastore-core'
const datastore = new MemoryDatastore()
const libp2p = await createLibp2p({
datastore,
transports: [
webSockets()
],
connectionEncryption: [
noise()
],
streamMuxers: [
yamux()
],
peerDiscovery: [
bootstrap({
list: [
"/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb",
"/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt"
]
})
],
services: {
identify: identifyService()
}
})
Since your Helia node is configured with a libp2p node, you can go to an IPFS Gateway and load the printed hash. Go ahead and try it!
> node 301-networking.js
Added file: bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa
# Copy that hash and load it on the gateway, here is a prefilled url:
# https://ipfs.io/ipfs/bafkreife2klsil6kaxqhvmhgldpsvk5yutzm4i5bgjoq6fydefwtihnesa
That's it! You just added and retrieved a file from the Distributed Web!
For more examples, please refer to the Documentation
Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are greatly appreciated.
- Fork the IPFS Project
- Create your Feature Branch (
git checkout -b feature/amazing-feature
) - Commit your Changes (
git commit -a -m 'feat: add some amazing feature'
) - Push to the Branch (
git push origin feature/amazing-feature
) - Open a Pull Request
The IPFS implementation in JavaScript needs your help! There are a few things you can do right now to help out:
Read the Code of Conduct and JavaScript Contributing Guidelines.
- Check out existing issues The issue list has many that are marked as 'help wanted' or 'difficulty:easy' which make great starting points for development, many of which can be tackled with no prior IPFS knowledge
- Look at the Helia Roadmap This are the high priority items being worked on right now
- Perform code reviews More eyes will help a. speed the project along b. ensure quality, and c. reduce possible future bugs
- Add tests. There can never be enough tests