• Stars
    star
    251
  • Rank 161,862 (Top 4 %)
  • Language
    JavaScript
  • License
    MIT License
  • Created about 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

The DHT powering Hyperswarm

hyperdht

See the full API docs at docs.holepunch.to

The DHT powering Hyperswarm

npm install hyperdht

Built on top of dht-rpc.

The Hyperswarm DHT uses a series of holepunching 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.

Usage

To try it out, first instantiate a DHT instance

import DHT from 'hyperdht'

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 (socket) {
  // socket is E2E encrypted between you and the other peer
  console.log('Remote public key', socket.remotePublicKey)

  // pipe it somewhere like any duplex stream
  process.stdin.pipe(socket).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 socket = anotherNode.connect(publicKey)

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

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

API

const node = new DHT([options])

Create a new DHT node.

Options include:

{
  // Optionally overwrite the default bootstrap servers, just need to be an array of any known dht node(s)
  // Defaults to ['node1.hyperdht.org:49737', 'node2.hyperdht.org:49737', 'node3.hyperdht.org:49737']
  bootstrap: ['host:port'],
  keyPair // set the default key pair to use for server.listen and connect
}

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 isolated DHT, start one 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. You'll need at least one persistent node for the network to be completely operational.

keyPair = DHT.keyPair([seed])

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.

await node.destroy([options])

Fully destroy this DHT node.

This will also unannounce any running servers. If you want to force close the node without waiting for the servers to unannounce pass { force: true }.

node = DHT.bootstrapper(port, host, [options])

If you want to run your own Hyperswarm network use this method to easily create a bootstrap node.

Creating P2P servers

const server = node.createServer([options], [onconnection])

Create a new server for accepting incoming encrypted P2P connections.

Options include:

{
  firewall (remotePublicKey, remoteHandshakePayload) {
    // validate if you want a connection from remotePublicKey
    // if you do return false, else return true
    // remoteHandshakePayload contains their ip and some more info
    return true
  }
}

You can run servers on normal home computers, as the DHT will UDP holepunch connections for you.

await server.listen(keyPair)

Make the server listen on a keyPair. To connect to this server use keyPair.publicKey as the connect address.

server.refresh()

Refresh the server, causing it to reannounce its address. This is automatically called on network changes.

server.on('connection', socket)

Emitted when a new encrypted connection has passed the firewall check.

socket is a NoiseSecretStream instance.

You can check who you are connected to using socket.remotePublicKey and socket.handshakeHash contains a unique hash representing this crypto session (same on both sides).

server.on('listening')

Emitted when the server is fully listening on a keyPair.

server.address()

Returns an object containing the address of the server:

{
  host, // external IP of the server,
  port, // external port of the server if predictable,
  publicKey // public key of the server
}

You can also get this info from node.remoteAddress() minus the public key.

await server.close()

Stop listening.

server.on('close')

Emitted when the server is fully closed.

Connecting to P2P servers

const socket = node.connect(remotePublicKey, [options])

Connect to a remote server. Similar to createServer this performs UDP holepunching for P2P connectivity.

Options include:

{
  nodes: [...], // optional array of close dht nodes to speed up connecting
  keyPair // optional key pair to use when connection (defaults to node.defaultKeyPair)
}

socket.on('open')

Emitted when the encrypted connection has been fully established with the server.

socket.remotePublicKey

The public key of the remote peer.

socket.publicKey

The public key of the local socket.

Additional peer discovery

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

{
  // Who sent the response?
  from: { id, 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, [relayAddresses], [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 can relay messages to you - 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.

Mutable/immutable records

const { 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.

const { value, from } = 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.

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

Store a mutable value in the DHT.

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

const { value, from, seq, signature } = await 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:

npm install -g hyperdht

Run a DHT node:

hyperdht # [--port 0] [--host 0.0.0.0] [--bootstrap <comma separated list of ip:port>]

Or run multiple nodes:

hyperdht --nodes 5 # [--host 0.0.0.0] [--bootstrap <list>]

Note: by default it uses the mainnet bootstrap nodes.

Isolated DHT network

To create your own DHT network is as follows:

  1. Run your first bootstrap node:
hyperdht --bootstrap --host (server-ip) # [--port 49737]

Important: it requires the port to be open.

Now your bootstrap node is ready to use at (server-ip):49737, for example:

const dht = new DHT({ bootstrap: ['(server-ip):49737'] })

Note: You could configure some DNS for the bootstrap IP addresses.

For the network to be fully operational it needs at least one persistent node.

  1. Provide the first node by using your own bootstrap values:
hyperdht --port 49738 --bootstrap (server-ip):49737

Important: it requires the port to be open too.

You need to wait ~30 mins for the node to become persistent.

Having persistent nodes in different places makes the network more decentralized and resilient!

For more information: examples/isolated-dht.mjs

License

MIT

More Repositories

1

hypercore

Hypercore is a secure, distributed append-only log.
JavaScript
2,403
star
2

hyperdrive

Hyperdrive is a secure, real time distributed file system
JavaScript
1,794
star
3

hyperswarm

A distributed networking stack for connecting peers.
JavaScript
926
star
4

sodium-native

Low level bindings for libsodium
JavaScript
302
star
5

hyperbee

An append-only B-tree running on a Hypercore
JavaScript
224
star
6

autobase

Autobase lets you write concise multiwriter data structures with Hypercore
JavaScript
84
star
7

corestore

A simple corestore that wraps a random-access-storage module
JavaScript
60
star
8

libudx

udx is reliable, multiplexed, and congestion-controlled streams over udp
C
40
star
9

hyperdrive-next

Hyperdrive is a secure, real-time distributed file system
JavaScript
37
star
10

hypercore-crypto

The crypto primitives used in hypercore, extracted into a separate module
JavaScript
36
star
11

hyperswarm-dht-relay

Relaying the Hyperswarm DHT over other transport protocols to bring decentralized networking to everyone
JavaScript
36
star
12

b4a

Bridging the gap between buffers and typed arrays
JavaScript
33
star
13

hyperblobs

A blob store for Hypercore
JavaScript
31
star
14

hypershell

Spawn shells anywhere. Fully peer-to-peer, authenticated, and end to end encrypted
JavaScript
31
star
15

hyperswarm-secret-stream

Secret stream backed by Noise and libsodium's secretstream
JavaScript
27
star
16

fs-native-extensions

Native file system extensions for advanced file operations
C
26
star
17

tiny-fs-native

Native fs for Javascript
JavaScript
24
star
18

keypear

πŸ”‘πŸ Keychain that derives deterministic Ed25519 keypairs and attestations
JavaScript
23
star
19

pear-expo-hello-world

C++
17
star
20

hyperswarm-seeders

A seeders only swarm
JavaScript
17
star
21

simple-seeder

Dead simple seeder with zero bugs
JavaScript
15
star
22

examples

Examples of basic flows for modules in the Holepunch ecosystem
JavaScript
15
star
23

noise-handshake

Simple noise handshake, supporting generic handshake patterns
JavaScript
13
star
24

localdrive

Hyperdrive but it is files
JavaScript
13
star
25

mirror-drive

Mirror two drives
JavaScript
12
star
26

tiny-http-native

Tiny HTTP library made purely on libuv and napi
JavaScript
12
star
27

libquickbit

The fastest bit in the West; a library for working with bit fields, accelerated using SIMD on supported hardware
C
11
star
28

drives

CLI to download, seed, and mirror a Hyperdrive or Localdrive
JavaScript
11
star
29

tiny-timers-native

Native timers for Javascript
JavaScript
9
star
30

udx-native

udx is reliable, multiplexed, and congestion-controlled streams over udp
JavaScript
9
star
31

libpearsync

Simple message passing between a libuv thread and something else
C
9
star
32

hyperswarm-doctor

Debugging tool for the swarm
JavaScript
7
star
33

netpaste

Copy and paste over the DHT
JavaScript
7
star
34

quickbit-universal

Universal wrapper for https://github.com/holepunchto/libquickbit with a JavaScript fallback
JavaScript
6
star
35

libcrc

Cross-platform implementation of CRC32 with hardware acceleration
C
6
star
36

hyperswarm-testnet

Small module to help you spin up a local Hyperswarm testnet
JavaScript
6
star
37

wasm-tools

A collection of useful tools for working with WASM/WAT in JavaScript
JavaScript
5
star
38

planb-summer-school

the workshop stuff
JavaScript
5
star
39

tt-native

https://github.com/holepunchto/libtt JavaScript bindings for Node.js
JavaScript
5
star
40

hypercore-id-encoding

Convert Hypercore keys to/from z-base32 or hex
JavaScript
4
star
41

serve-drive

HTTP drive server for entries delivery. Auto detects types like video, images, etc
JavaScript
4
star
42

autobase-test-helpers

Helpers when writing tests for an Autobased application
JavaScript
4
star
43

pear-radio-backend

Pear radio backend
JavaScript
4
star
44

nanodebug

A tiny, zero overhead debugging utility
JavaScript
4
star
45

crc-universal

Universal wrapper for https://github.com/holepunchto/libcrc with a JavaScript fallback
JavaScript
3
star
46

tiny-buffer-map

A very simple Map for Buffers and Uint8Arrays
JavaScript
3
star
47

quickbit-native

https://github.com/holepunchto/libquickbit JavaScript bindings for Node.js
JavaScript
3
star
48

tiny-paths

path for platforms without path
JavaScript
3
star
49

same-object

Determine if two objects are deeply equal
JavaScript
3
star
50

bare-expo

Example of embedding Bare in an Expo application using https://github.com/holepunchto/react-native-bare-kit
TypeScript
3
star
51

simdle-universal

Universal wrapper for https://github.com/holepunchto/libsimdle with a JavaScript fallback
JavaScript
2
star
52

libtt

Virtual console extensions built on libuv
C
2
star
53

cmake-ios

iOS utilities for CMake
CMake
2
star
54

cmake-binary

cmake binaries for windows, linux and macos
JavaScript
2
star
55

prebuild-containers

Containers for prebuilding native Node.js modules
Dockerfile
2
star
56

libsimdle

Simple and portable SIMD instructions for 128 bit vectors, inspired by the WASM SIMD specification
C
2
star
57

bits-to-bytes

Functions for doing bit manipulation of typed arrays
JavaScript
2
star
58

bare-addon

Template repository for creating Bare native addons
C
2
star
59

compact-encoding-bitfield

Compact codec for bitfields
JavaScript
2
star
60

seedbee

Bee for seeds
JavaScript
2
star
61

crc-native

https://github.com/holepunchto/libcrc JavaScript bindings for Node.js
Python
2
star
62

bare-utils

Node.js-compatible utility functions for Bare
JavaScript
2
star
63

bare-distributable-hello-world

Showing how to make a single distributable of a JS app
C
2
star
64

bare-debug-log

Simple debug log for JavaScript
JavaScript
2
star
65

pw-to-ek

Derive a secure encryption key from a password using the sodium's scrypt implementation.
JavaScript
2
star
66

cmake-drive

Drive utilities for CMake
1
star
67

cmake-bare-bundle

Bare bundling utilities for CMake
CMake
1
star
68

simdle-native

https://github.com/holepunchto/libsimdle JavaScript bindings for Node.js
C
1
star
69

native-pipe

Native named pipes
C
1
star
70

hp-rpc-cli

JavaScript
1
star
71

pear-inspect

JavaScript
1
star
72

drive-resolve

Asynchronous require resolution in Hyperdrive
JavaScript
1
star
73

warmup-encoding

Encode/decode sets of random blocks for warmup
JavaScript
1
star
74

framed-stream

Read/write stream messages prefixed 8, 16, 24 or 32 bit length
JavaScript
1
star
75

http-forward-host

Simple stream proxy that sniffs the HTTP host or x-forwarded-for header and allows you to to forward the stream based on that
JavaScript
1
star
76

hypertrace-prometheus

Add support for Prometheus/Grafana to hypertrace
JavaScript
1
star
77

bare-dns

Domain name resolution for JavaScript
C
1
star
78

fifofile

Userland FIFO file
JavaScript
1
star
79

bare-format

String formatting for JavaScript
JavaScript
1
star
80

secure-prompt

Securely prompt stdio using secure buffers
JavaScript
1
star
81

bare-headers

Development headers for Bare
JavaScript
1
star
82

bare-net

TCP and IPC servers and clients for JavaScript
JavaScript
1
star