@hyperswarm/dht

5.0.0-beta6 • Public • Published

@hyperswarm/dht

The DHT powering the HyperSwarm network

npm install @hyperswarm/dht

Built on top of dht-rpc.

The Hyperswarm DHT uses a series of hole punching techniques to make sure connectivity works on most networks, and is mainly used to facilitate finding and connecting to peers using end to end encrypted Noise streams.

NOTE: v5 Release Candidate

Note that this is the README for the v5 release candidate. To see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4

Usage

To try it out, first instantiate a DHT instance

const DHT = require('@hyperswarm/dht')
const node = new DHT()

Then on one computer listen for connections

// create a server to listen for secure connections
const server = node.createServer()

server.on('connection', function (noiseSocket) {
  // noiseSocket is E2E between you and the other peer
  // pipe it somewhere like any duplex stream

  console.log('Remote public key', noiseSocket.remotePublicKey)
  console.log('Local public key', noiseSocket.publicKey) // same as keyPair.publicKey

  process.stdin.pipe(noiseSocket).pipe(process.stdout)
})

// make a ed25519 keypair to listen on
const keyPair = DHT.keyPair()

// this makes the server accept connections on this keypair
await server.listen(keyPair)

Then on another connect to the computer using the public key of the key-pair it is listening on

// publicKey here is keyPair.publicKey from above
const noiseSocket = anotherNode.connect(publicKey)

noiseSocket.on('open', function () {
  // noiseSocket fully open with the other peer
})

// pipe it somewhere like any duplex stream
process.stdin.pipe(noiseSocket).pipe(process.stdout)

API

const node = new DHT([options])

Create a new HyperSwarm DHT node.

Options include:

{
  // Optionally overwrite the default bootstrap servers
  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']
  bootstrap: ['host:port']
}

See dht-rpc for more options as HyperDHT inherits from that.

Note: The default bootstrap servers are publicly served on behalf of the commons. To run a fully private DHT, start two or more dht nodes with an empty bootstrap array (new DHT({bootstrap:[]})) and then use the addresses of those nodes as the bootstrap option in all other dht nodes.

keyPair = DHT.keyPair([salt])

Use this method to generate the required keypair for DHT operations.

Returns an object with {publicKey, secretKey}. publicKey holds a public key buffer, secretKey holds a private key buffer.

If you pass any options they are forwarded to dht-rpc.

const stream = node.lookup(topic, [options])

Look for peers in the DHT on the given topic. Topic should be a 32 byte buffer (normally a hash of something).

The returned stream looks like this

{
  // The DHT id of the responding peer (hash of their address)
  id: <node-id-of-the-dht-peer>,
  // Who sent the response?
  from: { host, port },
  // What address they responded to (i.e. your address)
  to: { host, port },
  // List of peers announcing under this topic
  peers: [ { publicKey, nodes: [{ host, port }, ...] } ]
}

To connect to the peers you should afterwards call connect with those public keys.

If you pass any options they are forwarded to dht-rpc.

const stream = node.announce(topic, keyPair, [nodes], [options])

Announce that you are listening on a key-pair to the DHT under a specific topic.

When announcing you'll send a signed proof to peers that you own the key-pair and wish to announce under the specific topic. Optionally you can provide up to 3 nodes, indicating which DHT nodes you are "close" to in terms of XOR distance from the hash of your public key - this speeds up connects later on for other users.

An announce does a parallel lookup so the stream returned looks like the lookup stream.

Creating a server using dht.createServer automatically announces itself periodically on the key-pair it is listening on. When announcing the server under a specific topic, you can access the nodes it is close to using server.nodes.

If you pass any options they are forwarded to dht-rpc.

await node.unannounce(topic, keyPair, [options])

Unannounce a key-pair.

If you pass any options they are forwarded to dht-rpc.

await node.destroy()

Fully destroy this DHT node.

{ hash, closestNodes } = await node.immutablePut(value, [options])

Store an immutable value in the DHT. When successful, the hash of the value is returned.

If you pass any options they are forwarded to dht-rpc.

{ value, from, closestNodes } = await node.immutableGet(hash, [options])

Fetch an immutable value from the DHT. When successful, it returns the value corresponding to the hash.

If you pass any options they are forwarded to dht-rpc.

await { seq, closestNodes } = node.mutablePut(keyPair, value, [options])

Store a mutable value in the DHT.

If you pass any options they are forwarded to dht-rpc.

await { seq, value, from, closestNodes } = node.mutableGet(publicKey, [options])

Fetch a mutable value from the DHT.

Options:

  • seq - OPTIONAL, default 0, a number which will only return values with corresponding seq values that are greater than or equal to the supplied seq option.
  • latest - OPTIONAL - default false, a boolean indicating whether the query should try to find the highest seq before returning, or just the first verified value larger than options.seq it sees.

Any additional options you pass are forwarded to dht-rpc.

Additional API

See dht-rpc for the additional APIs the DHT exposes.

CLI

You can start a DHT node in the command line, using the @hyperswarm/cli package:

npm install -g @hyperswarm/cli
hyperswarm-dht # runs a DHT node

License

MIT

Readme

Keywords

none

Package Sidebar

Install

npm i @hyperswarm/dht@5.0.0-beta6

Version

5.0.0-beta6

License

MIT

Unpacked Size

63.9 kB

Total Files

14

Last publish

Collaborators

  • kasperisager
  • mafintosh
  • davidmarkclements