diff --git a/API/dht/README.md b/API/dht/README.md new file mode 100644 index 00000000..afabcf9b --- /dev/null +++ b/API/dht/README.md @@ -0,0 +1,108 @@ +DHT API +======= + +#### `findpeer` + +> Retrieve the Peer Info of a reachable node in the network. + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dht.findpeer(peerId, [callback]) + +Where `peerId` is a IPFS/libp2p Id of type [PeerId](https://github.com/libp2p/js-peer-id). + +`callback` must follow `function (err, peerInfo) {}` signature, where `err` is an error if the operation was not successful. `peerInfo` is an object of type [PeerInfo](https://github.com/libp2p/js-peer-info) + +If no `callback` is passed, a promise is returned. + +Example: + +```JavaScript +var id = PeerId.create() +ipfs.dht.findPeer(id, function (err, peerInfo) { + // peerInfo will contain the multiaddrs of that peer +}) +``` + +#### `findprovs` + +> Retrieve the providers for content that is addressed by an hash. + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dht.findprovs(hash, [callback]) + +Where `hash` is a multihash. + +`callback` must follow `function (err, peerInfos) {}` signature, where `err` is an error if the operation was not successful. `peerInfos` is an array of objects of type [PeerInfo](https://github.com/libp2p/js-peer-info) + +If no `callback` is passed, a promise is returned. + +Example: + +```JavaScript +ipfs.dht.findProvs(hash, function (err, peerInfos) {}) +``` + +#### `get` + +> Retrieve a value from DHT + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dht.get(key, [callback]) + +Where `key` is a string. + +`callback` must follow `function (err, value) {}` signature, where `err` is an error if the operation was not successful. `value` is the value that was stored under that key. + +If no `callback` is passed, a promise is returned. + +Example: + +```JavaScript +ipfs.dht.get(key, function (err, value) {}) +``` + +#### `put` + +> Store a value on the DHT + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dht.put(key, value, [callback]) + +Where `key` is a string and `value` can be of any type. + +`callback` must follow `function (err) {}` signature, where `err` is an error if the operation was not successful. + +If no `callback` is passed, a promise is returned. + +Example: + +```JavaScript +ipfs.dht.put(key, value, function (err) {}) +``` + + +#### `query` + +> Queries the network for the 'closest peers' to a given key. 'closest' is defined by the rules of the underlying Peer Routing mechanism. + +##### `Go` **WIP** + +##### `JavaScript` - ipfs.dht.query(peerId, [callback]) + +Where `peerId` is a IPFS/libp2p Id of type [PeerId](https://github.com/libp2p/js-peer-id). + +`callback` must follow `function (err, peerInfos) {}` signature, where `err` is an error if the operation was not successful. `peerInfos` is an array of objects of type [PeerInfo](https://github.com/libp2p/js-peer-info) + +If no `callback` is passed, a promise is returned. + +Example: + +```JavaScript +var id = PeerId.create() +ipfs.dht.query(id, function (err, peerInfos) { +}) +``` diff --git a/src/dht.js b/src/dht.js new file mode 100644 index 00000000..dd2dc7cc --- /dev/null +++ b/src/dht.js @@ -0,0 +1,90 @@ +/* eslint-env mocha */ +'use strict' + +const expect = require('chai').expect + +module.exports = (common) => { + describe('.dht', () => { + let ipfs + let peers + + before((done) => { + common.setup((err, factory) => { + expect(err).to.not.exists + factory.spawnNode((err, node) => { + expect(err).to.not.exist + ipfs = node + done() + }) + }) + }) + + after((done) => { + common.teardown(done) + }) + + describe('callback API', () => { + it('.get errors when getting a non-existent key from the DHT', (done) => { + ipfs.dht.get('non-existing', {timeout: '100ms'}, (err, value) => { + expect(err).to.be.an.instanceof(Error) + done() + }) + }) + it('.findprovs', (done) => { + ipfs.dht.findprovs('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP', (err, res) => { + expect(err).to.not.exist + + expect(res).to.be.an('array') + done() + }) + }) + }) + describe('promise API', () => { + it('.get errors when getting a non-existent key from the DHT', (done) => { + ipfs.dht.get('non-existing', {timeout: '100ms'}).catch((err) => { + expect(err).to.be.an.instanceof(Error) + done() + }) + }) + it('.findprovs', (done) => { + ipfs.dht.findprovs('Qma4hjFTnCasJ8PVp3mZbZK5g2vGDT4LByLJ7m8ciyRFZP').then((res) => { + expect(res).to.be.an('array') + done() + }).catch(done) + }) + }) + // Tests below are tests that haven't been implemented yet or is not + // passing currently + xdescribe('.findpeer', () => { + it('finds other peers', (done) => { + peers.a.ipfs.dht.findpeer(peers.b.peerID, (err, foundPeer) => { + expect(err).to.be.empty + expect(foundPeer.peerID).to.be.equal(peers.b.peerID) + done() + }) + }) + it('fails to find other peer, if peer doesnt exists', (done) => { + peers.a.ipfs.dht.findpeer('ARandomPeerID', (err, foundPeer) => { + expect(err).to.be.instanceof(Error) + expect(foundPeer).to.be.equal(null) + done() + }) + }) + }) + xit('.put and .get a key value pair in the DHT', (done) => { + peers.a.ipfs.dht.put('scope', 'interplanetary', (err, res) => { + expect(err).to.not.exist + + expect(res).to.be.an('array') + + // bug: https://github.com/ipfs/go-ipfs/issues/1923#issuecomment-152932234 + peers.b.ipfs.dht.get('scope', (err, value) => { + expect(err).to.not.exist + expect(value).to.be.equal('interplanetary') + done() + }) + }) + }) + xdescribe('.query', () => {}) + }) +} diff --git a/src/index.js b/src/index.js index ee35b234..33865f9b 100644 --- a/src/index.js +++ b/src/index.js @@ -7,3 +7,4 @@ exports.pin = require('./pin') exports.generic = require('./generic') exports.swarm = require('./swarm') exports.block = require('./block') +exports.dht = require('./dht')