Skip to content
This repository was archived by the owner on Mar 10, 2020. It is now read-only.

[WIP] Awesome API Documentation #469

Closed
wants to merge 3 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: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
test/setup/tmp-disposable-nodes-addrs.json
dist
coverage
docs
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ node_modules
coverage

test
docs
142 changes: 1 addition & 141 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -75,149 +75,9 @@ var ipfs = ipfsAPI('/ip4/127.0.0.1/tcp/5001')
var ipfs = ipfsAPI({host: 'localhost', port: '5001', procotol: 'http'})
```

### In a web browser through Browserify

Same as in Node.js, you just have to [browserify](http://browserify.org) the code before serving it. See the browserify repo for how to do that.

See the example in the [examples folder](/examples/bundle-browserify) to get a boilerplate.

### In a web browser through webpack

See the example in the [examples folder](/examples/bundle-webpack) to get an idea on how to use js-ipfs-api with webpack

### In a web browser from CDN

Instead of a local installation (and browserification) you may request a remote copy of IPFS API from [unpkg CDN](https://unpkg.com/).

To always request the latest version, use the following:

```html
<script src="https://unpkg.com/ipfs-api/dist/index.js"></script>
```

For maximum security you may also decide to:

* reference a specific version of IPFS API (to prevent unexpected breaking changes when a newer latest version is published)

* [generate a SRI hash](https://www.srihash.org/) of that version and use it to ensure integrity

* set the [CORS settings attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) to make anonymous requests to CDN

Example:

```html
<script src="https://unpkg.com/[email protected]/dist/index.js"
integrity="sha384-5bXRcW9kyxxnSMbOoHzraqa7Z0PQWIao+cgeg327zit1hz5LZCEbIMx/LWKPReuB"
crossorigin="anonymous"></script>
```

CDN-based IPFS API provides the `IpfsApi` constructor as a method of the global `window` object. Example:

```
var ipfs = window.IpfsApi('localhost', '5001')
```

If you omit the host and port, the API will parse `window.host`, and use this information. This also works, and can be useful if you want to write apps that can be run from multiple different gateways:

```
var ipfs = window.IpfsApi()
```

### CORS

In a web browser IPFS API (either browserified or CDN-based) might encounter an error saying that the origin is not allowed. This would be a CORS ("Cross Origin Resource Sharing") failure: IPFS servers are designed to reject requests from unknown domains by default. You can whitelist the domain that you are calling from by changing your ipfs config like this:

```bash
$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://example.com\"]"
$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials "[\"true\"]"
$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods "[\"PUT\", \"POST\", \"GET\"]"
```

## Usage

### API

> `js-ipfs-api` follows the spec defined by [`interface-ipfs-core`](https://github.com/ipfs/interface-ipfs-core), which concerns the interface to expect from IPFS implementations. This interface is a currently active endeavor - expect it to be complete in the next few weeks (August 2016). You can use it today to consult the methods available.

### Utility functions

Adding to the methods defined by [`interface-ipfs-core`](https://github.com/ipfs/interface-ipfs-core), `js-ipfs-api` exposes a set of extra utility methods. These utility functions are scoped behind the `ipfs.util`.

Complete documentation for these methods is coming with: https://github.com/ipfs/js-ipfs-api/pull/305


#### Add files or entire directories from the FileSystem to IPFS

> `ipfs.util.addFromFs(path, option, callback)`

Reads a file from `path` on the filesystem and adds it to IPFS. If `path` is a directory, use option `{ recursive: true }` to add the directory and all its sub-directories.

```JavaScript
ipfs.util.addFromFs('path/to/a/file', { recursive: true }, (err, result) => {
if (err) {
throw err
}
console.log(result)
})
```

`result` is an array of objects describing the files that were added, such as:

```
[{
path: 'test-folder',
hash: 'QmRNjDeKStKGTQXnJ2NFqeQ9oW23WcpbmvCVrpDHgDg3T6',
size: 2278
},
// ...
]
```

#### Add a file from a URL to IPFS

> `ipfs.util.addFromURL(url, callback)`

```JavaScript
ipfs.util.addFromURL('http://example.com/', (err, result) => {
if (err) {
throw err
}
console.log(result)
})

```

#### Add a file from a stream to IPFS

> `ipfs.util.addFromStream(stream, callback)`

This is very similar to `ipfs.files.add({path:'', content: stream})`. It is like the reverse of cat

```JavaScript
ipfs.util.addFromStream(<readable-stream>, (err, result) => {
if (err) {
throw err
}
console.log(result)
})
```

### Callbacks and promises

If you do not pass in a callback all API functions will return a `Promise`. For example:

```js
ipfs.id()
.then(function (id) {
console.log('my id is: ', id)
})
.catch(function(err) {
console.log('Fail: ', err)
})
```

This relies on a global `Promise` object. If you are in an environment where that is not
yet available you need to bring your own polyfill.
See https://ipfs.github.io/js-ipfs-api/

## Development

Expand Down
3 changes: 3 additions & 0 deletions documentation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
toc:
- name: Intro
file: intro.md
119 changes: 119 additions & 0 deletions intro.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
Installable via `npm install --save ipfs-api`, it can also be used directly in the browser.

## Quick Example

```js
const ipfsAPI = require('ipfs-api')

// connect to ipfs daemon API server

// leaving out the arguments will default to these values
const ipfs = ipfsAPI('localhost', '5001', {protocol: 'http'})

// or connect with multiaddr
const ipfs = ipfsAPI('/ip4/127.0.0.1/tcp/5001')

// or using options
const ipfs = ipfsAPI({host: 'localhost', port: '5001', procotol: 'http'})
```

There are more available, so take a look at the docs below for a full list. This documentation aims to be comprehensive, so if you feel anything is missing please create a GitHub issue for it.

## Download

The source is available for download from [GitHub](https://github.com/ipfs/js-ipfs-api). Alternatively, you can install using npm:

```bash
$ npm install --save ipfs-api
```

You can then `require()` ${name} as normal:

```js
const ipfsApi = require('ipfs-api')
```

## In the Browser

Ipfs-api should work in any ES2015 environment out of the box.

Usage:

```html
<script type="text/javascript" src="index.js"></script>
```

The portable versions of ipfs-api, including `index.js` and `index.min.js`, are included in the `/dist` folder. Ipfs-api can also be found on [unkpkg.com](https://unpkg.com) under

- https://unpkg.com/ipfs-api/dist/index.min.js
- https://unpkg.com/ipfs-api/dist/index.js

For maximum security you may also decide to:

* reference a specific version of IPFS API (to prevent unexpected breaking changes when a newer latest version is published)
* [generate a SRI hash](https://www.srihash.org/) of that version and use it to ensure integrity
* set the [CORS settings attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes) to make anonymous requests to CDN

Example:

```html
<script src="https://unpkg.com/[email protected]/dist/index.js"
integrity="sha384-5bXRcW9kyxxnSMbOoHzraqa7Z0PQWIao+cgeg327zit1hz5LZCEbIMx/LWKPReuB"
crossorigin="anonymous"></script>
```

CDN-based IPFS API provides the `IpfsApi` constructor as a method of the global `window` object. Example:

```
const ipfs = window.IpfsApi('localhost', '5001')
```

If you omit the host and port, the API will parse `window.host`, and use this information. This also works, and can be useful if you want to write apps that can be run from multiple different gateways:

```
const ipfs = window.IpfsApi()
```

## Frequently Asked Questions

### Running the daemon with the right port

To interact with the API, you need to connect to a running ipfs daemon running. It needs to be available on the right port. `5001` is the default, and is used in the examples below, but it can be set to whatever you need.

```sh
# Show the ipfs config API port to check it is correct
$ ipfs config Addresses.API
/ip4/127.0.0.1/tcp/5001
# Set it if it does not match the above output
$ ipfs config Addresses.API /ip4/127.0.0.1/tcp/5001
# Restart the daemon after changing the config

# Run the daemon
$ ipfs daemon
```

### CORS

In a web browser IPFS API (either browserified or CDN-based) might encounter an error saying that the origin is not allowed. This would be a CORS ("Cross Origin Resource Sharing") failure: IPFS servers are designed to reject requests from unknown domains by default. You can whitelist the domain that you are calling from by changing your ipfs config like this:

```bash
$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin "[\"http://example.com\"]"
$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials "[\"true\"]"
$ ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods "[\"PUT\", \"POST\", \"GET\"]"
```

### Callbacks and promises

If you do not pass in a callback all API functions will return a `Promise`. For example:

```js
ipfs.id()
.then(function (id) {
console.log('my id is: ', id)
})
.catch(function(err) {
console.log('Fail: ', err)
})
```

This relies on a global `Promise` object. If you are in an environment where none is available you need to bring your own polyfill.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
"release-minor": "gulp release --type minor",
"release-major": "gulp release --type major",
"coverage": "gulp coverage",
"coverage-publish": "aegir-coverage publish"
"coverage-publish": "aegir-coverage publish",
"docs": "aegir-docs"
},
"dependencies": {
"async": "^2.1.4",
Expand Down
17 changes: 17 additions & 0 deletions src/api/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ const promisify = require('promisify-es6')
const DAGNodeStream = require('../dagnode-stream')

module.exports = (send) => {
/**
* Add content to IPFS.
*
* @alias add
* @method
* @param {(Buffer|Stream|Array<Buffer|Stream>)} files - The content to add.
* @param {function(Error, {hash: string})} [callback]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we get the file in the callback rather than a String with the hash?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add only returns the hash as far as I know

* @returns {Promise<{hash: string}>|undefined}
*
* @memberof IpfsApi#
*
* @example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I understand our previous discussions, examples should make use of callbacks, not promises.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

feel free to change

* api.add(new Buffer('hello world')).then((res) => {
* console.log('saved with hash %s', res.hash)
* })
*
*/
return promisify((files, callback) => {
const ok = Buffer.isBuffer(files) ||
isStream.isReadable(files) ||
Expand Down
40 changes: 38 additions & 2 deletions src/api/bitswap.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,60 @@ const promisify = require('promisify-es6')

module.exports = (send) => {
return {
/**
* Show blocks currently on the wantlist.
*
* Print out all blocks currently on the bitswap wantlist for the local peer.
*
* @alias bitswap.wantlist
* @method
* @param {function(Error, Array<string>)} [callback]
*
* @returns {Promise<Array<string>>|undefined}
* @memberof IpfsApi#
*/
wantlist: promisify((callback) => {
send({
path: 'bitswap/wantlist'
}, callback)
}),

/**
* Show some diagnostic information on the bitswap agent.
*
* @alias bitswap.stat
* @method
* @param {function(Error, Object)} [callback]
*
* @returns {Promise<Object>|undefined}
* @memberof IpfsApi#
*/
stat: promisify((callback) => {
send({
path: 'bitswap/stat'
}, callback)
}),
unwant: promisify((args, opts, callback) => {

/**
* Remove a given block from your wantlist.
*
* @alias bitswap.unwant
* @method
* @param {string|Array<string>} key - The `base58` encoded multihashes of the blocks to unwant.
* @param {Object} [opts={}]
* @param {function(Error)} [callback]
*
* @returns {Promise<undefined>|undefined}
* @memberof IpfsApi#
*/
unwant: promisify((key, opts, callback) => {
if (typeof (opts) === 'function') {
callback = opts
opts = {}
}
send({
path: 'bitswap/unwant',
args: args,
args: key,
qs: opts
}, callback)
})
Expand Down
Loading