Skip to content
This repository has been archived by the owner on Feb 12, 2024. It is now read-only.

tutorial: Transfer Files #714

Closed
wants to merge 10 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .aegir.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,3 @@ module.exports = {
}]
}
}

2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,5 @@ node_modules

lib
dist

examples/transfer-files/complete/public/js/ipfs.js
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
</a>
<br>
<a href="https://waffle.io/ipfs/js-ipfs">
<img src="https://img.shields.io/badge/pm-waffle-yellow.svg?style=flat-square" />
<img src="https://img.shields.io/badge/pm-waffle-blue.svg?style=flat-square" />
</a>
<a href="https://github.com/ipfs/interface-ipfs-core">
<img src="https://img.shields.io/badge/interface--ipfs--core-API%20Docs-blue.svg">
Expand Down Expand Up @@ -137,7 +137,7 @@ The CLI is available by using the command `jsipfs` in your terminal. This is ali

### Use in the browser with browserify, webpack or any bundler

Simply require it as you would do for Node.js, but when transpiling+minifying with your bundler, make sure to swap `zlib` with a full replacement for the browser: `zlib: 'browserify-zlib-next'`. We have submited PR's to browserify and WebPack to make this as part of the standard node libraries that are transpiled, you can follow this development in [browserify](https://github.com/substack/node-browserify/issues/1672), [webpack](https://github.com/webpack/node-libs-browser/issues/51).
Simply require it as you would do for Node.js, but when transpiling+minifying with your bundler, make sure to swap `zlib` with a full replacement for the browser: `zlib: 'browserify-zlib-next'`. We have submitted PR's to browserify and WebPack to make this as part of the standard node libraries that are transpiled, you can follow this development in [browserify](https://github.com/substack/node-browserify/issues/1672), [webpack](https://github.com/webpack/node-libs-browser/issues/51).

You can also find examples of how to do this bundling at: `https://github.com/ipfs/js-ipfs/tree/master/examples`

Expand All @@ -151,18 +151,18 @@ The last published version of the package become [available for download](https:


```html
<!-- loading the minified version -->
<!-- loading the minified version -->
<script src="https://unpkg.com/ipfs/dist/index.min.js"></script>

<!-- loading the human-readable (not minified) version -->
<!-- loading the human-readable (not minified) version -->
<script src="https://unpkg.com/ipfs/dist/index.js"></script>
```

## Usage

### CLI

The `jsipfs` CLI, available when `js-ipfs` is installed globably, follows(should, it is a WIP) the same interface defined by `go-ipfs`, you can always use the `help` command for help menus.
The `jsipfs` CLI, available when `js-ipfs` is installed globally, follows(should, it is a WIP) the same interface defined by `go-ipfs`, you can always use the `help` command for help menus.

```sh
# Install js-ipfs globally
Expand Down Expand Up @@ -285,7 +285,7 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int

## Development

### Clone and install dependnecies
### Clone and install dependencies

```sh
> git clone https://github.com/ipfs/js-ipfs.git
Expand All @@ -297,7 +297,7 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int

```sh
# run all the unit tsts
> npm test
> npm test

# run just IPFS tests in Node.js
> npm run test:unit:node:core
Expand All @@ -319,7 +319,7 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int

```sh
# run all the interop tsts
> npm run test:interop
> npm run test:interop

# run just IPFS interop tests in Node.js using one go-ipfs daemon and one js-ipfs daemon
> npm run test:interop:node
Expand All @@ -332,7 +332,7 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int

```sh
# run all the interop tsts
> npm run test:benchmark
> npm run test:benchmark

# run just IPFS benchmarks in Node.js
> npm run test:benchmark:node
Expand Down Expand Up @@ -373,11 +373,11 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int
> tree src -L 2
src # Main source code folder
├── cli # Implementation of the IPFS CLI
   └── ...
└── ...
├── http-api # The HTTP-API implementation of IPFS as defined by http-api-spec
├── core # IPFS implementation, the core (what gets loaded in browser)
   ├── components # Each of IPFS subcomponent
   └── ...
├── components # Each of IPFS subcomponent
└── ...
└── ...
```

Expand Down
2 changes: 2 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ Let us know if you find any issue or if you want to contribute and add a new tut
- [How to bundle js-ipfs with WebPack](/bundle-webpack)

## Tutorials

- [Transfer files between a Browser node and Desktop node](/transfer-files)
7 changes: 5 additions & 2 deletions examples/basics/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@

const fs = require('fs')
const os = require('os')
const path = require('path')
const series = require('async/series')
const IPFS = require('../../src/core') // replace this by line below
const IPFS = require('../../src/core')
// replace this by line below if you are using ipfs as a dependency of your
// project
// const IPFS = require('ipfs')

/*
* Create a new IPFS instance, using default repo (fs) on default path (~/.ipfs)
*/
const node = new IPFS(os.tmpDir() + '/' + new Date().toString())
const node = new IPFS(path.join(os.tmpDir() + '/' + new Date().toString()))

const fileToAdd = {
path: 'hello.txt',
Expand Down
2 changes: 1 addition & 1 deletion examples/bundle-browserify/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ You should see the following:
## Special note

In order to use js-ipfs in the browser, you need to replace the default `zlib` library by `browserify-zlib-next`, a full implementation of the native `zlib` package, full in Node.js.
See the package.json to learn how to do this and avoid this pitfall. More context on: https://github.com/ipfs/js-ipfs#use-in-the-browser-with-browserify-webpack-or-any-bundler
See the package.json to learn how to do this and avoid this pitfall (see the `browser` key). More context on: https://github.com/ipfs/js-ipfs#use-in-the-browser-with-browserify-webpack-or-any-bundler
2 changes: 2 additions & 0 deletions examples/transfer-files/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
public/ipfs.js
220 changes: 220 additions & 0 deletions examples/transfer-files/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
# Tutorial - Transfer files between the browser and other IPFS nodes

> Welcome! This tutorial will help you build a tiny web application where you can fetch and add files to IPFS and transfer these between a go-ipfs node and a js-ipfs node.

There are a couple of caveats:

- js-ipfs currently doesn't support DHT peer discovery, the peer from which you are fetching data should be within the reach (local or in public IP) of the browser node.
- We need to use a signalling server to establish the WebRTC connections, this won't be necessary as soon as libp2p-relay gets developed
- [full go-ipfs interop is not complete yet, blocked by an interop stream multiplexer](https://github.com/ipfs/js-ipfs/issues/721)

That being said, we will explain throughout this tutorial to circunvent the caveats and once they are fixed, we will update the tutorial as well.

## Application diagram

The goal of this tutorial is to create a application with a IPFS node that dials to other instances of it using WebRTC, and at the same time dial and transfer files from a Desktop IPFS node using WebSockets as the transport.

┌──────────────┐ ┌──────────────┐
│ Browser │ │ Browser │
│ │ WebRTC │ │
│ │◀─────────────────▶│ │
│ │ │ │
└──────────────┘ └──────────────┘
▲ ▲
│ │
│ │
│ │
│WebSockets WebSockets│
│ │
│ │
│ ┌──────────────┐ │
│ │ Desktop │ │
│ │ │ │
└───────▶│ │◀─────────┘
│ │
└──────────────┘

## Check out the final state

If you just want to check out what is the final state of how this application will look like, go to the complete folder, install the dependencies and run it.

```sh
> cd complete
> npm install
> npm start
# open your browser (Chrome or Firefox) in http://localhost:12345
```

You should get something like this:

TODO: Insert final screenshot here

## Step-by-step instructions

Here's what we are going to be doing, today:

- 1. Set up, install a go-ipfs node in your machine
- 2. Make your daemons listen on WebSockets
- 3. Initialize the project
- 4. Create the frame for your IPFS enabled app
- 5. Add and cat a file
- 6. Use WebRTC to dial between browser nodes
- 7. Dial to a node using WebSockets (your Desktop ones)
- 8. Transfer files between all of your nodes, have fun!

Let's go.

### 1. Set up

You'll need to have an implementation of IPFS running on your machine. Currently, this means either go-ipfs or js-ipfs.

Installing go-ipfs can be done by installing the binary [here](https://ipfs.io/ipns/dist.ipfs.io/#go-ipfs). Alternatively, you could follow the instructions in the README at [ipfs/go-ipfs](https://github.com/ipfs/go-ipfs).

Installing js-ipfs requires you to have node and [npm](https://www.npmjs.com). Then, you simply run:

```sh
> npm install --global ipfs
...
> jsipfs --help
Commands:
...
```

This will alias `jsipfs` on your machine; this is to avoid issues with `go-ipfs` being called `ipfs`.

At this point, you have either js-ipfs or go-ipfs running. Now, initialize it:

```
> ipfs init
```

or

```
> jsipfs init
```

This will set up an `init` file in your home directory.

### 2. Make your daemons listen on WebSockets

At this point, you need to edit your `config` file, the one you just set up with `{js}ipfs init`. It should be in either `~/.jsipfs/config` or `~/.ipfs/config`, depending on whether you're using JS or Go. You can run `cat ~/.jsipfs/config` to see the contents of the JSON file.

Since websockets are currently not stable and are experimental, you'll need to add the ability for your daemon to listen on Websocket addresses. Look into your init file (using `cat`) and find the `Addresses` block:

```json
"Addresses": {
"Swarm": [
"/ip4/0.0.0.0/tcp/4002"
],
"API": "/ip4/127.0.0.1/tcp/5002",
"Gateway": "/ip4/127.0.0.1/tcp/9090"
}
```

To make Websockets work, open up the `config` file and add the following entry to your `Swarm` array: `/ip4/0.0.0.0/tcp/9999/ws`. Now, it should look like this:


```json
"Addresses": {
"Swarm": [
"/ip4/0.0.0.0/tcp/4002",
"/ip4/0.0.0.0/tcp/9999/ws"
],
"API": "/ip4/127.0.0.1/tcp/5002",
"Gateway": "/ip4/127.0.0.1/tcp/9090"
}
```

Now it should listen on Websockets. We're ready to start the daemon.

```sh
> ipfs daemon
```

(Again, either `jsipfs` or `ipfs` works. I'll stop explaining that from here on out.)

You should see the Websocket address in the output:

```sh
Initializing daemon...
Swarm listening on /ip4/127.0.0.1/tcp/4001
Swarm listening on /ip4/127.0.0.1/tcp/9999/ws
Swarm listening on /ip4/192.168.10.38/tcp/4001
Swarm listening on /ip4/192.168.10.38/tcp/9999/ws
API server listening on /ip4/127.0.0.1/tcp/5001
Gateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080
Daemon is ready
```

It's there in line 5 - see the `/ws`? Good. that means it is listening.

### 3. Start the WebApp project


Now, you'll need to make sure you are in `js-ipfs/examples/transfer-files/complete`. You'll see a `package.json`: this manifest holds the information for which packages you'll need to install to run the webapp. Let's install them, and then start the project:

```sh
> npm install
> npm start
```

You should see this text:

```sh
Starting up http-server, serving public
Available on:
http://127.0.0.1:12345
http://192.168.1.24:12345
Hit CTRL-C to stop the server
```

Go to http://127.0.0.1:12345 in your browser; you're now in the webapp, if all went well.

### 4. Create the frame for your IPFS enabled app

TODO: Not sure what this means.

### 5. Add and cat a file

### 6. Use WebRTC to dial between browser nodes
### 7. Dial to a node using WebSockets (your Desktop ones)
### 8. Transfer files between all of your nodes, have fun!

--------

## Start the example

**NOTE!** Before running the examples, you need to build `js-ipfs`. You can do this by following the instructions in https://github.com/ipfs/js-ipfs#clone-and-install-dependnecies and then building it as per https://github.com/ipfs/js-ipfs#build-a-dist-version.

```
npm install
npm start
```

Open http://127.0.0.1:8080 in a browser.

**TODO: add instructions how to cat a hash in the UI.**

## Tutorial

Steps
1. create IPFS instance

TODO. See `./start-ipfs.js`

3. add a file in go-ipfs
4. copy file's hash
5. ipfs.files.cat

TODO. add ipfs.files.cat code examples from index.html

6. output the buffer to <img>

```
...
stream.on('end', () => {
const blob = new Blob(buf)
picture.src = URL.createObjectURL(blob)
})
```
1 change: 1 addition & 0 deletions examples/transfer-files/complete/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
js/ipfs.js
Loading