{"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"8299d1a600867a27ae56eefc9abf90a9d9bdd4b8","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-1.1.0-rc1.tgz","fileCount":18,"integrity":"sha512-wfdUyHlWhUmDxB9Uufn9T67YOOS6nJqA+GGjiH2dLjTnnU/A/nvH91ftegOyR2t8LAWU//EM04Ov4GNMDsV2bg==","signatures":[{"sig":"MEUCIQDKxGf/oXvZoeyoDlgvTWU5p8NGLlCa5uNcmjqyQdND1AIgdIadZEL0Lf6RuDHmujviPF3Ksvd3kSsu1oNu9knITB8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86181,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdUu84CRA9TVsSAnZWagAAPZ4P/1a2t6CPTXlS+q0VgFTK\nYkQGPMscS3Mo6OnT7fPNrwUgtE6PaZGFhiPDH3QWjt98LYdr6VDiDQNsdXg8\naRLc4svCF8wLjbVYl87Y4NWQRRkMWFdEv6gdp4g9YpIAT0AFkkFm9B/oBEq3\nhfm8lYYQiUMUmPZhliegoCY14sPU/lqnAQMsfzoS9pWx/odgCYV5qfr4AkIp\nmUtq9+f+dYpc/KBjnyGJAi6BGCxSOH5irwUe+hM36Mq18LbGhVUSNstOZxZ2\nxcNrPKWLLYbJD0zhH4F/RbK+XmlEaA5/vzEN5h8Tc/1yLg6glNALaap/++6W\nmefQDwiI2pAk8laejGNHzFahjSW2ghU/jKIqGO3FuhwAwdgDfwfei7b+Oi3y\nNvHqyLJE6MeN3vdV/awHH6bxYXDJgOm9gDudvoW0Ajz7eyM/8WSbK6aou7uQ\nlkKu28IWFKvejlneVyMo5+qrQW4dP8JDFBIZK78nA1Fd2zDc12BEE2GE5zAn\nW3H+vrFXzQ0PsEGe8TP7lyyyiDamkwhuuVfCGl3xr/yPx+ciQ8dbFLaDRBKB\nSbzMutNQPGlxvAJlIJ+H4tt3hD9zD/XmgXu3YoyXlIv9FGS1Cq8NsPa9ZRXE\nb4J6A5xd3pYIu3h/yNSSL+U8R5/y9nWi63RqrtRSoHXAbalB/dr7syBlq7fD\nxSZC\r\n=UwFy\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 the HyperSwarm stack\n\n```\nnpm install @hyperswarm/dht\n```\n\n## Usage\n\n``` js\nconst dht = require('@hyperswarm/dht')\nconst crypto = require('crypto')\n\nconst node = dht({\n  // just join as an ephemeral node\n  // as we are shortlived\n  ephemeral: true\n})\n\nconst topic = crypto.randomBytes(32)\n\n// announce a port\nnode.announce(topic, { port: 12345 }, function (err) {\n  if (err) throw err\n\n  // try and find it\n  node.lookup(topic)\n    .on('data', console.log)\n    .on('end', function () {\n      // unannounce it and shutdown\n      node.unannounce(topic, { port: 12345 }, function () {\n        node.destroy()\n      })\n    })\n})\n```\n\n## API\n\n#### `const node = dht([options])`\n\nCreate a new HyperSwarm DHT node.\n\nOptions include:\n\n```js\n{\n  // Optionally overwrite the default bootstrap servers\n  bootstrap: ['host:port'],\n  // If you are a shortlived client or don't want to host\n  // data join as an ephemeral node. (defaults to false)\n  ephemeral: true,\n  // time until a peer is dropped\n  maxAge: 12 * 60 * 1000\n}\n```\n\n#### `node.holepunch(peer, [callback])`\n\nUDP holepunch to another peer.\n\n`peer` should be a `{ host, port, referrer: { host, port } }`,\nwhere referrer should be the host and port of the DHT node who told you about this peer.\n\n#### `const stream = node.lookup(topic, [options], [callback])`\n\nLook for peers in the DHT on the given topic. Topic should be a 32 byte buffer (normally a hash of something).\n\nOptions include:\n\n```js\n{\n  // Optionally set your public port. This will make\n  // other peers no echo back yourself\n  port: 12345,\n  // Optionally look for LAN addresses as well by\n  // passing in your own. Will also exclude yourself from\n  // the results. Only LAN addresses announced on the\n  // same public IP and sharing the first two parts (192.168)\n  // will be included.\n  localAddress: {\n    host: '192.168.100.100',\n    port: 20000\n  }\n}\n```\n\nThe returned stream looks like this\n\n```js\n{\n  // The DHT node that is returning this data\n  node: { host, port },\n  // List of peers\n  peers: [ { host, port }, ... ],\n  // List of LAN peers\n  localPeers: [ { host, port }, ... ]\n}\n```\n\nIf you pass the callback the stream will be error handled and buffered.\n\n#### `const stream = node.announce(topic, [options], [callback])`\n\nAnnounce a port to the dht.\n\nOptions include:\n\n```js\n{\n  // Explicitly set the port you want to announce.\n  // Per default you UDP socket port is announced.\n  port: 12345,\n  // Optionally announce a LAN address as well.\n  // Only people with the same public IP as you will\n  // get these when doing a lookup\n  localAddress: {\n    host: '192.168.100.100',\n    port: 20000\n  }\n}\n```\n\nAn announce does a parallel lookup so the stream returned looks like the lookup stream.\nIf you pass a callback the stream will be error handled and buffered.\n\n#### `node.unannounce(topic, [options], [callback])`\n\nUnannounce a port. Takes the same options as announce.\n\n#### `node.destroy()`\n\nFully destroy this DHT node.\n\n#### `node.listen([port])`\n\nExplicitly listen on a UDP port.\nIf you do not call this it will use a random free port.\n\n\n#### `node.immutable.put(value, callback = (err, key) => {}) => stream`\n\nStore an immutable value in the DHT. When successful, the second argument passed\nto `callback` contains the generated key (a hash) for that value.\n\n\n#### `node.immutable.get(key, callback = (err, value, info) => {}) => stream`\n\nFetch an immutable value from the DHT. When successful, the second argument passed to `callback` contains the resolved value. The third argument `info` is an object containing `id` which is the ID of the responding Node.\n\n#### `node.immutable.get(key) => stream`\n\nFetch all matching immutable values from the DHT. \n\nAny values found are emitted in a `data` event where the data object takes the form: `{id, value}`. The `id` is the ID of the responding Node.\n\n#### `node.mutable.keypair()`\n\nUse this method to generate the required keypair for a put.\nReturns an object with `{publicKey, secretKey}`. `publicKey` holds a public key buffer, `secretKey` holds a private key buffer.\n\n#### `node.mutable.salt(size = 32)`\n\nUtility method for creating a random salt value. This can optionally\nbe passed in `mutable.put` and `mutable.get` options.\nSalt values can be used as a sort of secondary UID, allowing multiple values to be stored under the same public key. Min `size` is 16 bytes, max `size` is 64 bytes.\n\n#### `node.mutable.sign(value, options)`\n\nUtility method which can be used to create a `sig`.\n\nThe options are the exact same as those of `mutable.put` (except `sig`).\n\nOptions:\n\n* `keypair` – REQUIRED, use `node.mutable.keypair` to generate this.\n* `salt` - OPTIONAL - default `undefined`, a buffer >= 16 and <= 64 bytes. If supplied it will salt the signature used to verify mutable values.\n\n#### `node.mutable.signable(value, options)`\n\nUtility method which returns the exact buffer that would be signed in `mutable.put`\n(that does not provide a `sig`). This is only needed when using a salt, otherwise\nit will return the same `value` passed in. This method is to facilitate out-of-band\nsigning (e.g. hardware signing), do not pass the returned signable value into \n`mutable.sign`, `mutable.sign` already uses `mutable.signable`.\n\nOptions:\n\n* `salt` - OPTIONAL - default `undefined`, a buffer >= 16 and <= 64 bytes. If supplied it will salt the signature used to verify mutable values.\n\n#### `node.mutable.put(value, options, callback = (err, { key, ...info }) => {}) => stream`\n\nStore a mutable value in the DHT.\n\nOptions:\n\n* `keypair` – REQUIRED, use `node.mutable.keypair` to generate this.\n* `sig` - OPTIONAL, a buffer holding an ed25519 signature corresponding to public key. This can be supplied instead of a secret key which can be useful for offline signing. If `sig` is supplied `keypair` must only contain a `publicKey` and no `secretKey`. See `signable` and `sign`.\n* `seq` - OPTIONAL - default `0`, a number which should be increased every time put is passed a new value for the same keypair\n* `salt` - OPTIONAL - default `undefined`, a buffer >= 16 and <= 64 bytes. If supplied it will salt the signature used to verify mutable values.\n\nWhen successful the second argument passed to `callback` is an object containing the public key as `key`, with additional meta data (`...info`): `sig`, `seq`, `salt`. \n\n#### `node.mutable.get(key, [options], callback = (err, { value, ...info }) => {}) => stream`\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* `salt` - OPTIONAL - default `undefined`, a buffer >= 16 and <= 64 bytes. If supplied it will salt the signature used to verify mutable values.\n\nWhen successful, the second argument passed to `callback` is an object containing the resolved `value` with additional meta data (`...info`): `sig`, `seq` and `salt`.\n\n#### `node.immutable.get(key) => stream`\n\nFetch all matching mutable values from the DHT.\n\nAny values found are emitted in a `data` event where the data object takes the form: `{id, value, sig, seq, salt}`. The `id` is the ID of the responding Node.\n\n#### Put / Get Stream Interface\n\nAll mutable and immutable Put / Get methods return a stream.\n\nIn addition to usual Node.js stream behaviour, the returned stream \nwill emit `warning` events which may contain error information from other\nNodes. The stream instance also has the following stat counters\n\n* `inflight` - how many requests are currently active/ongoing\n* `responses` - how many responses have been received\n* `errors` - how many errors occured (locally)\n* `updates` - how many updates were made\n\n#### `node.on('listening')`\n\nEmitted when the node starts listening\n\n#### `node.on('close')`\n\nEmitted when the node is fully closed.\n\n#### `node.on('announce', topic, peer)`\n\nEmitted when an announce is received.\n\n#### `node.on('unannounce', topic, peer)`\n\nEmitted when an unannounce is received.\n\n#### `node.on('lookup', topic, peer)`\n\nEmitted when a lookup is received.\n\n## CLI\n\nThere is a CLI available as well.\n\n```sh\nnpm install -g @hyperswarm/dht\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"ae693041e1832031509a7fef69929df18087a095","license":"MIT","scripts":{"ci":"standard && npm test","cov":"tap -R classic --100 --coverage-report=html test/*.test.js","test":"tap  -R classic test/*.test.js  && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},"homepage":"https://github.com/hyperswarm/dht","repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.4.1","description":"The DHT backing the HyperSwarm stack","directories":{},"maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"_nodeVersion":"8.16.0","dependencies":{"dht-rpc":"^4.1.6","hashlru":"^2.3.0","ipv4-peers":"^2.0.0","record-cache":"^1.1.0","end-of-stream":"^1.4.1","sodium-universal":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tap":"^14.5.0","get-port":"^5.0.0","standard":"^13.1.0","nonsynchronous":"^1.0.1","protocol-buffers":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/dht_1.1.0-rc1_1565716279848_0.3405386698790662","host":"s3://npm-registry-packages"},"_id":"@hyperswarm/dht@1.1.0-rc1","version":"1.1.0-rc1"}