From ff2069aeec58bea7953ab6324a0cffbf512660ce Mon Sep 17 00:00:00 2001 From: interfect Date: Mon, 17 Oct 2016 19:14:11 -0700 Subject: [PATCH] Expose Buffer on ipfs objects, add examples This lets you construct a Buffer even in browser code that doesn't have access to the Node Buffer global, so that you can pass it back to IPFS API calls that want a Buffer. Add some usage documentation Mentions the `ipfs.Buffer` field you can use to stamp out `Buffer`s so you can actually insert stuff given just an `IPFS` instance and no Node.js APIs in scope. Also add examples for using IPFS in browser with a script tag, and for using libp2p-webrtc-star. --- README.md | 45 ++++++++++++ examples/browser-script/README.md | 13 ++++ examples/browser-script/index.html | 85 ++++++++++++++++++++++ examples/libp2p-webrtc-star/README.md | 14 ++++ examples/libp2p-webrtc-star/index.html | 99 ++++++++++++++++++++++++++ src/core/index.js | 3 + 6 files changed, 259 insertions(+) create mode 100644 examples/browser-script/README.md create mode 100644 examples/browser-script/index.html create mode 100644 examples/libp2p-webrtc-star/README.md create mode 100644 examples/libp2p-webrtc-star/index.html diff --git a/README.md b/README.md index 37d51f21c2..866ef1f831 100644 --- a/README.md +++ b/README.md @@ -39,6 +39,8 @@ Consult the [Roadmap](/ROADMAP.md) for a complete state description of the proje - [HTTP-API](#http-api) - [IPFS Core examples (use IPFS as a module)](#ipfs-core-examples-use-ipfs-as-a-module) - [Create a IPFS node instance](#create-a-ipfs-node-instance) + - [Add a file](#add-a-file) + - [Retrieve a file](#retrieve-a-file) - [More to come](#more-to-come) - [API](#api) - [Generic API](#generic-api) @@ -48,6 +50,7 @@ Consult the [Roadmap](/ROADMAP.md) for a complete state description of the proje - [Files API](#files-api) - [Swarm API](#swarm-api) - [libp2p API](#libp2p-api) + - [Domain data types](#domain-data-types) - [Development](#development) - [Clone](#clone) - [Install Dependencies](#install-dependencies) @@ -148,6 +151,8 @@ The HTTP-API exposed by the js-ipfs daemon follows the [`http-api-spec`](https:/ #### Create a IPFS node instance +The basic startup flow involves (optionally) creating a Repo, creating an IPFS node, `init`-ing it so it can generate its keys, `load`-ing its configuration, and putting it online with `goOnline`. Here is a structural example: + ```JavaScript // IPFS will need a repo, it can create one for you or you can pass // it a repo instance of the type IPFS Repo @@ -179,6 +184,38 @@ node.init({ emptyRepo: true, bits: 2048 }, (err) => { > We are working on making this init process better, see https://github.com/ipfs/js-ipfs/issues/556 for the discussion. +Below are some more examples of JavaScript IPFS in action. + +#### Add a file + +Once you have an IPFS node up and running, you can add files to it from `Buffer`s, `Readable` streams, or [arrays of objects of a certain form](https://github.com/ipfs/interface-ipfs-core/tree/master/API/files#add). If you don't have `Buffer` conveniently available (say, because you're in a browser without the Node API handy), it's available as a property of the IPFS node. + +```javascript +// Add a single file +node.files.add(node.Buffer.from('Hello world'), (err, returned) => { + if (err) { + throw err + } + console.log('IPFS hash: ', returned[0].hash) +}) +``` + +#### Retrieve a file + +To retrieve the contents of a file, you can use the [cat method](https://github.com/ipfs/interface-ipfs-core/tree/master/API/files#cat), which will call your callback with a Node.js-style `Readable` stream. + +```javascript +node.files.cat('QmNRCQWfgze6AbBCaT1rkrkV5tJ2aP4oTNPb5JZcXYywve', + (err, content_stream) => { + if (err) { + throw err + } + content_stream.on('data', (buffer) => { + console.log('File contents:', buffer.toString('ascii')) + }) +}) +``` + #### More to come > If you have built an example, please share it with the community by submitting a Pull Request to this repo!. @@ -208,6 +245,12 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int - [libp2p-ipfs-nodejs](https://github.com/ipfs/js-libp2p-ipfs-nodejs) - [libp2p-ipfs-browser](https://github.com/ipfs/js-libp2p-ipfs-browser) +#### Domain data types + +IPFS exposes the Buffer class in every ipfs instance, so that you can create buffers and add them to IPFS just like if you were using it in Node.js. + +You can get it at `ipfs.Buffer` + ## Development ### Clone @@ -225,6 +268,8 @@ Every IPFS instance also exposes the libp2p API at `ipfs.libp2p`. The formal int ### Run Tests +#### Block Service + ```sh > npm test diff --git a/examples/browser-script/README.md b/examples/browser-script/README.md new file mode 100644 index 0000000000..41f006600d --- /dev/null +++ b/examples/browser-script/README.md @@ -0,0 +1,13 @@ +# Use IPFS in the browser with ` +``` + +This exposes a global `Ipfs`; you can get a node by making a `new Ipfs()`. + +See `index.html` for a working example. + + diff --git a/examples/browser-script/index.html b/examples/browser-script/index.html new file mode 100644 index 0000000000..f8ef09adb1 --- /dev/null +++ b/examples/browser-script/index.html @@ -0,0 +1,85 @@ + + + + IPFS in the Browser + + + + +

IPFS in the Browser

+

This page creates an IPFS node in your browser and drops it into the global Javascript namespace as ipfs. Open the console to play around with it.

+

Note that opening two tabs of this page in the same browser won't work well, because they will share node configuration. You'll end up trying to run two instances of the same node, with the same private key and identity, which is a Bad Idea.

+
Node status: offline
+ + diff --git a/examples/libp2p-webrtc-star/README.md b/examples/libp2p-webrtc-star/README.md new file mode 100644 index 0000000000..5debdc60fc --- /dev/null +++ b/examples/libp2p-webrtc-star/README.md @@ -0,0 +1,14 @@ +# Robust Initialization and libp2p-webrtc-star Signaling + +There's still a bit of work required to start up an in-browser node in a robust way, so that it will work whether or not there is an existing initialized IPFS repo in the user's browser. If there isn't one, you need to call `init` as above, but if there is one, calling `init` will fail. Moreover, there's currently no good way to check if you need to call `init` or not. + +Also, an in-browser node isn't able to call up normal IPFS nodes over raw TCP; it can only communicate over Websockets and WebRTC. Currently, there are no Websockets or WebRTC bootstrap nodes run by the IPFS maintainers. You will probably want to set up a [libp2p-webrtc-star signaling server](https://github.com/libp2p/js-libp2p-webrtc-star) so nodes used in your application can find each other: + +```bash +npm i libp2p-webrtc-star -g +star-sig +``` + +You will then want to point IPFS nodes used in your application at your signaling server, so they can connect to each other. This is accomplished by adding an address to the node's configuration referencing the signaling server, of the form `/libp2p-webrtc-star/ip4//tcp//ws/ipfs/`, where `` is the peer ID of the node that the address is being added to. This causes the node to think of itself as being contactable through the signaling server. It will then initializes its libp2p-webrtc-star implementation and automatically peer with other nodes using the same server. + +The `index.html` page in this directory is an example which initializes an IPFS node in a browser safely, whether a node has already been initialized by the current domain or not. It also configures `libp2p-webrtc-star` communication, using a signaling server running on the local host. (Note that since IPFS node configuration information is stored in IndexedDB in browsers, opening two tabs of this code from a local file in the same browser won't work, because they'll share the same node keys and identity. Either run the code from multiple domains, or run it in two different browsers, like Chrome and Firefox.) diff --git a/examples/libp2p-webrtc-star/index.html b/examples/libp2p-webrtc-star/index.html new file mode 100644 index 0000000000..f614a806aa --- /dev/null +++ b/examples/libp2p-webrtc-star/index.html @@ -0,0 +1,99 @@ + + + + IPFS in the Browser with WebRTC + + + + +

IPFS in the Browser with WebRTC

+

This page creates an IPFS node in your browser and drops it into the global Javascript namespace as ipfs. Open the console to play around with it.

+

Note that opening two tabs of this page in the same browser won't work well, because they will share node configuration. You'll end up trying to run two instances of the same node, with the same private key and identity, which is a Bad Idea.

+
Node status: offline
+

Run a libp2p-webrtc-star signaling server! Peers detected through the server will be displayed below:

+

Peers:

+
+ + diff --git a/src/core/index.js b/src/core/index.js index a58836c10c..a1bf893ffe 100644 --- a/src/core/index.js +++ b/src/core/index.js @@ -67,4 +67,7 @@ function IPFS (repoInstance) { this.files = files(this) this.bitswap = bitswap(this) this.ping = ping(this) + + // expose Buffer for browser applications + this.Buffer = Buffer }