{"bin":{"hyperswarm-dht":"bin.js"},"bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"f4a44398f1f1126deb740fd58e55196ea6443344","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.0.1.tgz","fileCount":35,"integrity":"sha512-W7XR916cHUXwULRCXwAhV2hfeXgvtaJl/cho65pdYl08dGyx23ktjGUU9zaOtdWwm8M+/AfsrcQTJEkbNhe9zA==","signatures":[{"sig":"MEUCIQDk/be6MLJ+AwLY70/Bl0RCIbAIpO4Elno+yrAw5pQtUQIgSnBFstX4uDbrycVmBJQxNdUDGRYbJEucBcGb4/O/KMY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":133206,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJirgoPACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmr/vA/+JLSSps4qnNWybp5sKrzG0n/cvj486mMP3r0AWLuPqQBkL+fR\r\nqK8xrlfiLoNCLNE2YKFcgtWjHxHH503Poftv2Et73/4mPra2kqmYcQG6Rvjz\r\nIGlPDH9UWeWjLPovJzq3/M7zrXVEpPTTRSuxXkNr25LapeMK0RS5ohwAB9JQ\r\n1qkVYeuwprVgjP/oQlqAJZ2F98kKBBHxK2oB3rA/bPzbeF5mmQPM8VT6H+Qu\r\nzjWulWxGPVanpHUzWrxfPCz32ewBn0Ki3KjRY5rhG+XxrcoJvtUPxRsf2V+6\r\nesrrJucFqMc2ksR56AfqBS+P183/GsLkaXseBZJ8rAA2dBmVU+iuJiNPgnll\r\nynWEVrAvey7qQddAsSq3UHeZWf5ZBeYfR5bkkjNGnRjNhA8OyzaEtWl7aBQu\r\nhPNy2tmAcqXr2IetziDRzM0WxgI/0qOf4klb/hwIxzB03DSQWKwShKjB1L3B\r\n5lnAwCXi6hwcST6O7S41mKWAEnz6uMwW0NuQn0iXY2pybqIqTD4b9ZbjhLM2\r\n+wxffy6yO1mFHzBiA9goz4GxuZDfh5Vsp+9QOnvV08DXA4YVx9pSpEfSLnQB\r\nJb/sKNkf7VD+GkXWo1Ah+UIS7MSJ2XQIas3bEvs6igs1Y+EnkJUdVlNLvMKq\r\nx47XzsNYFCe78pXmzRxVpIv4byS7TlCQcqI=\r\n=le5s\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","name":"@hyperswarm/dht","author":{"url":"@mafintosh","name":"Mathias Buus"},"readme":"# @hyperswarm/dht\n\nThe DHT powering Hyperswarm\n\n```\nnpm install @hyperswarm/dht\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of holepunching techniques to make sure connectivity works on most networks,\nand is mainly used to facilitate finding and connecting to peers using end to end encrypted Noise streams.\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nimport DHT from '@hyperswarm/dht'\n\nconst node = new DHT()\n```\n\nThen on one computer listen for connections\n\n``` js\n// create a server to listen for secure connections\nconst server = node.createServer()\n\nserver.on('connection', function (noiseSocket) {\n  // noiseSocket is E2E between you and the other peer\n  // pipe it somewhere like any duplex stream\n\n  console.log('Remote public key', noiseSocket.remotePublicKey)\n  console.log('Local public key', noiseSocket.publicKey) // same as keyPair.publicKey\n\n  process.stdin.pipe(noiseSocket).pipe(process.stdout)\n})\n\n// make a ed25519 keypair to listen on\nconst keyPair = DHT.keyPair()\n\n// this makes the server accept connections on this keypair\nawait server.listen(keyPair)\n```\n\nThen on another connect to the computer using the public key of the key-pair it is listening on\n\n``` js\n// publicKey here is keyPair.publicKey from above\nconst noiseSocket = anotherNode.connect(publicKey)\n\nnoiseSocket.on('open', function () {\n  // noiseSocket fully open with the other peer\n})\n\n// pipe it somewhere like any duplex stream\nprocess.stdin.pipe(noiseSocket).pipe(process.stdout)\n```\n\n## API\n\n#### `const node = new DHT([options])`\n\nCreate a new HyperSwarm DHT node.\n\nOptions include:\n\n```js\n{\n  // Optionally overwrite the default bootstrap servers, just need to be an array of any known dht node(s)\n  // Defaults to ['node1.hyperdht.org:49737', 'node2.hyperdht.org:49737', 'node3.hyperdht.org:49737']\n  bootstrap: ['host:port'],\n  keyPair // set the default key pair to use for server.listen and connect\n}\n```\n\nSee [dht-rpc](https://github.com/mafintosh/dht-rpc) for more options as HyperDHT inherits from that.\n\n*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.\n\n#### `keyPair = DHT.keyPair([seed])`\n\nUse this method to generate the required keypair for DHT operations.\n\nReturns an object with `{publicKey, secretKey}`. `publicKey` holds a public key buffer, `secretKey` holds a private key buffer.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n#### `await node.destroy([options])`\n\nFully destroy this DHT node.\n\nThis will also unannounce any running servers.\nIf you want to force close the node without waiting for the servers to unannounce pass `{ force: true }`.\n\n#### `node = DHT.bootstrapper(port, [options])`\n\nIf you want to run your own Hyperswarm network use this method to easily create a bootstrap node.\n\n## Creating P2P servers\n\n#### `const server = node.createServer([options], [onconnection])`\n\nCreate a new server for accepting incoming encrypted P2P connections.\n\nOptions include:\n\n```js\n{\n  firewall (remotePublicKey, remoteHandshakePayload) {\n    // validate if you want a connection from remotePublicKey\n    // if you do return false, else return true\n    // remoteHandshakePayload contains their ip and some more info\n    return true\n  }\n}\n```\n\nYou can run servers on normal home computers, as the DHT will UDP holepunch connections for you.\n\n#### `await server.listen(keyPair)`\n\nMake the server listen on a keyPair.\nTo connect to this server use keyPair.publicKey as the connect address.\n\n#### `server.refresh()`\n\nRefresh the server, causing it to reannounce its address. This is automatically called on network changes.\n\n#### `server.on('connection', encryptedConnection)`\n\nEmitted when a new encrypted connection has passed the firewall check.\n\n`encryptedConnection` is a [NoiseSecretStream](https://github.com/mafintosh/noise-secret-stream) instance.\n\nYou can check who you are connected to using `encryptedConnection.remotePublicKey` and `encryptedConnection.handshakeHash` contains a unique hash representing this crypto session (same on both sides).\n\n#### `server.on('listening')`\n\nEmitted when the server is fully listening on a keyPair.\n\n#### `server.address()`\n\nReturns an object containing the address of the server:\n\n```js\n{\n  host, // external IP of the server,\n  port, // external port of the server if predictable,\n  publicKey // public key of the server\n}\n```\n\nYou can also get this info from `node.remoteAddress()` minus the public key.\n\n#### `await server.close()`\n\nStop listening.\n\n#### `server.on('close')`\n\nEmitted when the server is fully closed.\n\n## Connecting to P2P servers\n\n#### `const encryptedConnection = node.connect(remotePublicKey, [options])`\n\nConnect to a remote server. Similar to `createServer` this performs UDP holepunching for P2P connectivity.\n\nOptions include:\n\n```js\n{\n  nodes: [...], // optional array of close dht nodes to speed up connecting\n  keyPair // optional key pair to use when connection (defaults to node.defaultKeyPair)\n}\n```\n\n#### `encryptedConnection.on('open')`\n\nEmitted when the encrypted connection has been fully established with the server.\n\n#### `encryptedConnection.remotePublicKey`\n\nThe public key of the remote peer.\n\n#### `encryptedConnection.publicKey`\n\nThe connections public key.\n\n## Additional peer discovery\n\n#### `const stream = node.lookup(topic, [options])`\n\nLook for peers in the DHT on the given topic. Topic should be a 32 byte buffer (normally a hash of something).\n\nThe returned stream looks like this\n\n```js\n{\n  // Who sent the response?\n  from: { id, host, port },\n  // What address they responded to (i.e. your address)\n  to: { host, port },\n  // List of peers announcing under this topic\n  peers: [ { publicKey, nodes: [{ host, port }, ...] } ]\n}\n```\n\nTo connect to the peers you should afterwards call `connect` with those public keys.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n#### `const stream = node.announce(topic, keyPair, [relayAddresses], [options])`\n\nAnnounce that you are listening on a key-pair to the DHT under a specific topic.\n\nWhen 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.\n\nAn announce does a parallel lookup so the stream returned looks like the lookup stream.\n\nCreating 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`.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n#### `await node.unannounce(topic, keyPair, [options])`\n\nUnannounce a key-pair.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n## Mutable/immutable records\n\n#### `{ hash, closestNodes } = await node.immutablePut(value, [options])`\n\nStore an immutable value in the DHT. When successful, the hash of the value is returned.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n#### `{ value, from } = await node.immutableGet(hash, [options])`\n\nFetch an immutable value from the DHT. When successful, it returns the value corresponding to the hash.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n#### `await { publicKey, closestNodes, seq, signature } = node.mutablePut(keyPair, value, [options])`\n\nStore a mutable value in the DHT.\n\nIf you pass any options they are forwarded to dht-rpc.\n\n#### `await { value, from, seq, signature } = node.mutableGet(publicKey, [options])`\n\nFetch a mutable value from the DHT.\n\nOptions:\n\n* `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.\n* `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.\n\nAny additional options you pass are forwarded to dht-rpc.\n\n## Additional API\n\nSee [dht-rpc](https://github.com/mafintosh/dht-rpc) for the additional APIs the DHT exposes.\n\n## CLI\n\nYou can start a DHT node in the command line, with the bundled cli tool:\n\n```sh\nnpm install -g @hyperswarm/dht\nhyperswarm-dht # runs a DHT node\nhyperswarm-dht --bootstrap # runs a DHT node with bootstrap settings\nhyperswarm-dht --nodes 5 # runs 5 nodes\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"d915f5714dccb5ce77093466100410db2e634fd5","license":"MIT","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"homepage":"https://github.com/hyperswarm/dht#readme","keywords":[],"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.5.5","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"_nodeVersion":"16.15.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.0.0","udx-native":"^1.1.0","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^1.0.2","noise-handshake":"^2.1.0","compact-encoding":"^2.4.1","debugging-stream":"^2.0.0","hypercore-crypto":"^3.3.0","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^6.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.0.1_1655573007475_0.2149396706845741","host":"s3://npm-registry-packages"},"_id":"@hyperswarm/dht@6.0.1","version":"6.0.1"}