{"_id":"@hyperswarm/dht","_rev":"113-f8fddcc56c44e5fac3ef8489b2802ce0","name":"@hyperswarm/dht","dist-tags":{"next":"5.0.25","latest":"6.5.1"},"versions":{"0.0.0":{"name":"@hyperswarm/dht","version":"0.0.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@0.0.0","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"dist":{"shasum":"3c48c681150e81b047d7648f61d1c9a2aac752ee","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-0.0.0.tgz","fileCount":8,"integrity":"sha512-pKCTz9FD6rajzEv5BW8mWl1+h3r1j6GvfQaVFvYg3lJbSV9pjEmHIoK6qSaWs4LDlv15f9cLV5RSOOo/5y+vRQ==","signatures":[{"sig":"MEUCIQDz9YgKS9fEev/eJTpEQ6v/oGELE8PyiSXPoS2l/EqDzQIgb1bg+9bWE8nzUJeRMGncLVlsnRlcoFQGxNvBvqs8AnE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":15730,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbqoLfCRA9TVsSAnZWagAAUlcP/i6kEbA7ewC8B0kmN9O9\n8lBIYcUpdHBGvy0eGs37JH0vaj1M+LdlKXLdnsWtf4E89pQ75aOzgWuKo74S\nx8TWXh1NssiJpTqYDRdGMaJdXHDq2/vR7lmCm1IkHAnFtPmZhungKWl4aF0c\nVkmLABsRSEb1FcAlRlUmY6cxrUz+R0OSk8wnz7vQYIfcD12DVGRWdVrOJ7b5\nAEEOhi4foaaDi3ZfZgr/kHq8y0oHh8bZsqDQ6K3ANfHHhcXdyygu6FbzoTlL\nE5hE23Ryv/soWw0x25A3vzilBCIwyRAj83EfJVDtHOxplJxlLrmo3a0Cat15\noQ3G/xWxpjOaWfWduFWXd/Dvy4PNCogVB6ydyRcUAoIyw2+Vufn/XVC/XbbT\ni2vkTS5cKISU++mI4O9nAaTZwE0Qb2C9kEa732wCoVQF6ITIyGnzlPg+fp1H\njOjTtKFNriXwmY7YSS+aR9FCvPpGncXYdHFuzWsyiuxOzlxFkaKggiaIFqO+\n1LelfyGX0rHa+15SV4GJc6QdhwU0Ou3k1bbWIHslLDwufKu8x0loK3O0Szwu\nY7/7DnYfahB+DTaTtNPzlfgsbJwk6n+h51ddgOLq8gd4IEldFT9luN6MEAxJ\nxzaCWDsZ4/zHL0MUZzUFY9hcSmPES8A31JiG66/gJF88+8T3jQ4Dug+OMrqG\n1VuS\r\n=4KJM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"15fd722c3bf8bbe9f3c6c23186185b4a5890f665","scripts":{"test":"standard","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.2.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.11.0","dependencies":{"dht-rpc":"^4.0.1","ipv4-peers":"^1.1.1","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"standard":"^12.0.1","protocol-buffers":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/dht_0.0.0_1537901278870_0.9824614816752095","host":"s3://npm-registry-packages"}},"0.0.1":{"name":"@hyperswarm/dht","version":"0.0.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@0.0.1","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"dist":{"shasum":"edca49ea643a1036492d489654a03b76f2b4de40","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-0.0.1.tgz","fileCount":8,"integrity":"sha512-ocwfEAXVuiuqaMPNUcBVCZn9pguRYBTjCYiI/fwbnEYInzkPGo/KG/aWBSkKqN9lpKAWXRFLYJrgo7VDnAMCpg==","signatures":[{"sig":"MEYCIQC9IGc8wkGAj/tXDBlSoyUL8id3uuK/M57imVXz+v19UgIhAK3pcrofAnlz9aFA06oCX4aXcr6fLqJN2m8UmmlBsrmA","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":15759,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbqoUACRA9TVsSAnZWagAAUJIP/2CfaW4eZf0j411iGdQR\niDN9WgSknOXzhk8aDsYHBFZBHJ1jNVqFNxdJ225gkGGsRfu+3hPf6muEYgNC\nIPfvZZUXHn77XaRlHsYDd91Tlxf/EA2/il45sn2/WMuiyQUflPxu+AoAyjuj\nqWfmSnjaCJ6SEfbLFv38vUxW2U5YDlLY0HpJTLrLj2XWy706tLnO39kerFp5\nchK07xAcXKyUYPtAUQw+ZkZATGYwnPKpdgfm5XjxPTTmxWErTl2qqiN51WD/\nrS6gzBlSPXYeNyn6GAf3Xo4uryJoQDVUL0z7/XwzUa6YNTvJrlXeeUHDYDS5\noEAMwLsLCO3Sm34AwR2P+tXBAa1HLLI8v6lO9oQ7yznafgMfqt2Fg4oOMVy+\nqv0IaBWenaytEqREzkFtNmE1HYe9qcqSCTJG9rsP+M7Ug/44PgKYLyF9RHBL\nwTgT76cO2ZEgZ7Fkyp+ewE4c3lHEZw2f4Lu2oMxGUyvAGgFHwMRZNkQz6fvJ\ntUROvwmNUStnVwR6TetBHzooRg4x5Lk72X8nY3yNJP+4YsFQBg/sHyV2JLfl\nrbg9xbN0OEodjuw0Ra1CctQlKkSehTqcfegn9XvEojfrDGxwMrAZgR8AB79V\nEpSWVioTIQPDaQzNwG9cwXsf/EtnmbgbAm5opPxohq2WjsBl6x2AqRTibect\n38rl\r\n=W9pd\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"3d650df25a161423140b4f255e4904583cf7a4bd","scripts":{"test":"standard","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.2.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.11.0","dependencies":{"dht-rpc":"^4.0.1","ipv4-peers":"^1.1.1","record-cache":"^1.1.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"standard":"^12.0.1","protocol-buffers":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/dht_0.0.1_1537901823583_0.5364673421132151","host":"s3://npm-registry-packages"}},"0.1.0":{"name":"@hyperswarm/dht","version":"0.1.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@0.1.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"dist":{"shasum":"fc4c0d895fced16c738ef8fdbf6337b4b78df4ea","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-0.1.0.tgz","fileCount":8,"integrity":"sha512-coR84vFQIqfAtmTsnELQqlOjqQQqksWqJm3dxHPS+hg2vdK0bzdXumsQItSEOZhyXE4Ho8qIsSKvpxWTAcc3yQ==","signatures":[{"sig":"MEQCIAF/2k6PtwGfDI57OIt1ugKrgD0/MBbBItb3RI/SSLBuAiAiHAcr6Uz0sAvrvfMURs0yImQ9dIBasDLUZyPcXfXWAg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":15847,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdH2ZICRA9TVsSAnZWagAAn4IP/0ErfjouaRCcYIO4IBum\niLCzzt6zI30860YklpPke4GjxRq8AJEe7FkT5AoUvbH+5qYEbQs4Xb3k3MDS\n5mUKiYoHLVrUT11ZANxBOlp6WSdZ89+d1B+B02tlIlKDd8R3KToXOM3zufGF\nfnnIGeQEFK1GBESNiu6f+/BHT0gLV+IV4eoJe0b4+H542UeEYByfPENGoxH/\nEyAlof8WUTYguZNXrI1Y9rWs97FJIBihjQ/IzTZiW0eplTm/YsQOLuQuJaKZ\nXl5JOtqnHrTuwSu5RreBhBFxQ0GZB9715Msko2I1Es3EhTF/KSH6RixD2Iw2\nU+Lh7mkjLlIykuzOWZ+k6m2M6SCrENHbp0gEfaqMMiyLJMtmw1nG4HJxmnbL\no5S+pAnUZeDYxSn3o0icp/oza0kXEeitfj6t3zob/U/noltnat1c8BYNmxvz\nF2I0xlDRidlTCved0YrFaTNmFujxdz3hzb8WZ4uhK7fcoxbbYHcJlL7DyMS9\nPdffBxObicaLk6jDnap6Ae91jmdSNr+JWYtu8BJIIGeZifnptpH7sWJcOUcW\nepfui8ecOjzdk/fOYHymQyiXU//W+oXc5HdccavxwdJT7JIV2ZVrT25b6fHd\nKR6E4pCBpQLypwJmtbudDgM1um4xwhrkt0dWayD4g0+GQ1nQ/+hqsXl2t+Pq\na5Vz\r\n=9Ie3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"c1af35e3291b4ced2614f3c818b33cd0991f95bf","scripts":{"test":"standard","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.16.0","dependencies":{"dht-rpc":"^4.0.1","ipv4-peers":"^1.1.1","record-cache":"^1.1.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"standard":"^12.0.1","protocol-buffers":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/dht_0.1.0_1562338887644_0.18857100645484381","host":"s3://npm-registry-packages"}},"0.2.0":{"name":"@hyperswarm/dht","version":"0.2.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@0.2.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"dist":{"shasum":"3460d2265c78ad7ae5335a4408e0868bb0e49e56","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-0.2.0.tgz","fileCount":8,"integrity":"sha512-InZRaTYtf/KgkD8VhTsl1rR+m9b4ilJomBpJQbyGjk9PW+ovZkayo3v+cylXMXoxul8eUjY1uQTL18d2t245Zg==","signatures":[{"sig":"MEUCIEkCtgLpPnNl8317DuK3VwWyL6ZH7BC9xLCtXRWO6dMQAiEAth/IAuu1MOLYWXX/q5VF5RQzE1z/cHxLhSdnWx82Ytk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":15898,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLIdnCRA9TVsSAnZWagAAD4MP/A8gKoSMXkjCvGtzA+Ce\nU8wkOV5Hqc/96GQ1G/8EColF2k37AXTLj5jqlRk5bqR5C6q8jHZ0gtKV4TUC\nRij33hAJ6DL1NRDkHB1dNPicuI8JmM9muFPX7tYxitOJXYLOYKfi8X8D4w91\nlkxEBI9aYGF+VscIFAAGxGGPBI/AL1jjmpACvvBGL10wAy+q//UJfQhUDRXo\nfrtnV/vpcDDYwNYAyUTBIcluRucnIJpdot3nSLjAOvcGoMUyNv11NxzhpWa4\nA6JAHIe5b85nGwEwfkg5RutveDwXnHoEtEEfSdpf4LIDmEgR0vPLaa2p8v93\nIk4pumhlBjwAV8xbiWCcAu5zkX5Le45ms0Qb0pR1Ce6yFwmaD+UmyqnExerN\nsRxAKR3oX2vSbDkhARHHhCsxg7azAzYTaW036mS8j38xkGzBA25WqvOqTgMi\nTBo2OTGI1doSNFFnFAzIPzAPcNYE0L0fG+4nPu/SzXbvI5mPk9yz7Bew/5ty\nDwSbev/AXkbpAM61AY2PCWFFEDi0V7Jbnd0tn4tngeYuUA7+n7sbflPFBor6\n0HxkdK6HICvzCHHBgGv1Vo2RPL7FjKOJbiIVnSSR9Hx/vLsQF9fhr5M7N58/\n9J7U5kOHnBciOVC20sOi1qu+WqxEXsGah3clIu/uFUw2TGwF8DN1ATpcKXWi\nFFve\r\n=EYVL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"96fa7d699b8283065b3f0922d54c8c432909d682","scripts":{"test":"standard","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.16.0","dependencies":{"dht-rpc":"^4.0.1","ipv4-peers":"^1.1.1","record-cache":"^1.1.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"standard":"^12.0.1","protocol-buffers":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/dht_0.2.0_1563199335095_0.8947560605562073","host":"s3://npm-registry-packages"}},"0.2.1":{"name":"@hyperswarm/dht","version":"0.2.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@0.2.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"dist":{"shasum":"ff6ac4723435e6b29c92e67bfc53843482c893db","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-0.2.1.tgz","fileCount":8,"integrity":"sha512-R+bNhYZX03R52iZzp8hMATlRsFJ1bJyNPAAfxU/G+SO/Uy0PO3WxQ5z1cB7Twzpkq/ENUfY+CzhEILnL7wLlBQ==","signatures":[{"sig":"MEQCIA3Lq+9vcBulGZXAmaIetPGDeTPby+AneWgGb6Acbor4AiAscM7TYh4U88FJ7//IW/9YXt2NqD7Ktb7+bxsiu0APBA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":15898,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdLIomCRA9TVsSAnZWagAAkJwP/Rtjvkpn7LG4Ik0d962n\nsC1Upm89gb3TA0x6TVffG/vduutkAZR+lh/DIgcOI3iZ/YvQ1SN2aiSN16aH\ncL8K0Qg7ODauk9meOPsgYltBzNlNyieVH9qJniiXCMLfwGu84rKenM3yYIUQ\ncEBRRbpWk45hH+RUq8pAnajnXbl6nMAR/5LG4wtSrgQu4v+PRNouoebXKn5r\nHQKR4CFgOaFk+Xy3rC/RpMBIZ7rpYfpmBFN5iOEmwoGGaQiYULc9ssM/euZg\nAqPB9uP2m6ibnZLLzHkThMfaBO2hTvaJdxQ2WVVOj5CyurhNHWndlJLn6m5r\npKVJkZSDGRcyNLbJZlJHB4fnwY53nhr5M4IfGYB/MWfEGBCIS/gYxbOM+cCM\npOKoP8Vx1++66oY1FCYD9RSTn+oFd2O6cQVLZYS7TWHzSEjnzhPZH5T46+S7\n5Drp26ZA+1DaPY2ALGd8p5oJwSFk/ei+JURGNHwMSW1ZTj74qxyw9ByaKnp8\nZVZRWbg7Nd+liIDCXVoX7acN0ChK9728KAt3+HWxrr11J+nl5SC3Gnc/Vx8t\nfIqZ5DCWU7uaUGLcAM8cAUgkx60v+ZPkEhSFCMoSKX5qwYji3XA902QUcC1E\nkJVPKuMk/20FXdSfpIWACdOu0eZbppMV4Ujf5STG/EEStPeQODnGTTfRc+wv\n2iqX\r\n=TFl2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"153d0fb498cc8ba106e64ba23612e28ee250a447","scripts":{"test":"standard","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.16.0","dependencies":{"dht-rpc":"^4.0.1","ipv4-peers":"^1.1.1","record-cache":"^1.1.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"devDependencies":{"standard":"^12.0.1","protocol-buffers":"^4.1.0"},"_npmOperationalInternal":{"tmp":"tmp/dht_0.2.1_1563200038150_0.1805411014280882","host":"s3://npm-registry-packages"}},"1.0.0":{"name":"@hyperswarm/dht","version":"1.0.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@1.0.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"c26265a6422c03c3bc1ab1ed91f07c838cb5e316","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-1.0.0.tgz","fileCount":18,"integrity":"sha512-tfg2K44ddpQZ7M25Lys3gDtXIK+5EcUA5sAGOCLtANGNjXc1T8qYLlviJIWdo0ucKnrEJK8Ag+7L3U9hbNTyFg==","signatures":[{"sig":"MEYCIQDCPGAfcNBH4V/t5/y4o7vJBmLokXHH7vfADzjQGBwaWwIhALDAkeVxLz1YI4BybuJcA/B+drNnLU5ceNRK0N/k/ekm","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":75773,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdSogvCRA9TVsSAnZWagAA+sAP/25juPncfSSlqg6cc4GU\nZwfxzytdbi5OJN3Oh4m+xX+tQ9V9/yHCJjJYRD+C2miPfyL39uRwck5STM2x\nc+tcKfuGIasromeKtsBJj+kDFekGaI/77JoSuvtr48eQW/1iRJb00LuUC1c5\n/xTsyuz5B+mb5UeJiK5w/kPUlNWpFWrQSkmIj+3NVktVu3f+2XmW7uYO1JC1\nY0dXGYbP7ZJ/08NJEjGnaOkSpO3yWINNxdGTb0L/lIxxEDmtLLy2WyqBfYWA\nGnBbZWVv63YfzEk8yn4vilQRjDLxHnUuI53f9MLOGmyqA99NoVRBzmHVlLtB\nC66F989Stl0K63lk1sRBuF1h9S2PN5tRmXBm+ByxTAFoDrmjwnx+phXDsDFV\n7iEJKi5ZZXxdwr0mRr2OZNKwaL1zdPvr30f5oHq7Z4rEya8JLqDJ09lpUMyL\nqUpUcRBka5Mz+lEc9iPn8nqX98T/PjUOLZVNFXF8zbihFvN4pr++IKNYx1PI\njyMjBud7iloTqQZQuiZagX7aphMoSrdmL0QHVLcwLQ8PGhA3i3BhPpC8xA2S\nADHi//UBcNWzj3rLdw1VHsxWYy2cFQNHoEr/zdJ3PdBvECSqTTczC36g/Cje\nDMmDwA2qEZgr5ttwgiF5tUeVWnKitn9Fa8eyM0uuPh/tV2nadkYXXJ8MFQoO\n/l9P\r\n=OSLl\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"8b5dc98b7e52164366f95ba1f7d048fbbf17c0ac","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":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.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,"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.0.0_1565165615160_0.8751450479353775","host":"s3://npm-registry-packages"}},"1.0.1":{"name":"@hyperswarm/dht","version":"1.0.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@1.0.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"61e796adba227699008041741d17dc878af59d13","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-1.0.1.tgz","fileCount":18,"integrity":"sha512-bmJyX4dWy28ZiuL3+zMJug226gVvBmXcCUKXe55g1JtoXwPgXch+ENIrB03/sBrXfYffAGFUlWKNHflVe9FNzw==","signatures":[{"sig":"MEQCIE1qyAVAWZAy9EcYIxyiuwkGcIFnWfVYZSvbT5oXKwzrAiBaH6j/vi6V86K92pbOdfbBlZ0ALiyIT8II8zZeLZEREw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":75937,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdTHmKCRA9TVsSAnZWagAARDEQAJqh3In+PHFd2Bnc49gU\nQtlUbN/fkPkNBMWZWEw8aEq2mvTvah1Hbo0RPpokpdegmcMzqOpyJMor5Gjz\nXExdNyKRLIPsYHKieMoASLUhN+w32D5VpjgnXqWDJb9zhHL7xa2r1YzQWg4R\nXlMUEQvdRkhtZr+cgQ+HIQwLZwJEXfUy+25MwD5y77rfbflUt32ZA5C00CMp\nGQWu/Z/XEyFmmoWjjBqMKo/TNPCbPeMuQRu1Pe0aAFj4EVtTMX6YRj4NmY6x\nSDKbowvKh2bzxJVDZLmv8jl1fkllkNSbn6gMWy2/l9xYroYNYLkZAu8Nw2+Z\n4liz5bf0j3+5nHLJWvdQbS69p0Agc+YqO0XFwmDTfDb/5mWnqhtpe/VJd7li\n5uVVGCMuJkQhlTcCPMV9QTJbXqX6fIq4A4+vAgD0yzHojmXVKeR2+YVLLPk/\nIX+XhdhiH4wk0vie/NjcPMXlXPVexdjSaa2Dy9VGzETzlPJSeGPCDhxRLOuH\n5pjy0fUNNTRc7GIRGYphTQXo2te6kKIkWbwAZmNyHM/GLRiOiZo2scfwCwvw\ngOF/+iJeMlADFn8VcqB9J/dwYV8ZfOectskTpG5EeD6WMr7kzwzpxpyeKA9o\nynttpyQ0LwO2egOo5Qe3FJdro/PS4aoIaQLeD4IGe4eA5+zQV37+QWWWafl6\n+AdX\r\n=gDOi\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"30b541307bde90e6965f134ecb9e8963f2b9be2f","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"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.4.1","description":"The DHT backing the HyperSwarm stack","directories":{},"_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,"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.0.1_1565292937705_0.6060277474621925","host":"s3://npm-registry-packages"}},"1.1.0-rc1":{"name":"@hyperswarm/dht","version":"1.1.0-rc1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@1.1.0-rc1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"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","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","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"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.4.1","description":"The DHT backing the HyperSwarm stack","directories":{},"_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"}},"1.1.0-rc2":{"name":"@hyperswarm/dht","version":"1.1.0-rc2","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@1.1.0-rc2","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"81d37d1f7bffe14e058818a012f2827b91028954","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-1.1.0-rc2.tgz","fileCount":18,"integrity":"sha512-S0TGtwIkDXNK/yommKhSL4bcDeLs3sMZ1VHwnspomYTO0/8sepSjsayZiQ91RqmaMLRK6+fWKbBlikuoiFsw1Q==","signatures":[{"sig":"MEQCIDB4jyuKUOwQ4ZItbXvBFDUr/xHSOyCdiqQAFMT5Di03AiAkiFl9CIAtQhWtnOHGG183Hy/j6GDa56ACJ/bfm+6d1w==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":84822,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdU0YCCRA9TVsSAnZWagAAbQsP/RplVGwMRHrgWmkSXl5O\nIxt1cROx8faO8WBGbh3gDYJm6xHdp+kDiLkzbBj0OIizarzSm9GW83MmwikD\nVaHblk3aSQnSv3MZ5osaE/c7N5xzxtSGZJH6nAMowdDBB1MH4SnMxtB79vYJ\nWj+jDpSuUAYoviQOXGhNQwxgbY0uFQIF/TY3vr270zEpmp+InebnW2lBmWEI\nXweoO+Hg/uSl/1/RtimoMJ1+KY5/0ZR0D/oltF002kNJ2+cwbo2uYtDNDwBV\nT0mTgZgo5y8P3ah1QlhrqWtG61UYv+zNDwu21FG9uu9ib7ziRiemKN0++VHz\nxlhaC7lT8tt4JSMkTzZjcyFwosfmd8ublVq3yXRxJYRt5twqVXsLaRFZBgaX\nq/LaIhN4FLA4qG4PynMir/GDt7M05MQLqrenh8oWwOXdT/UqAE6URl0INYNa\nzT+nfTH9ytUs27sO2+WP8MNzEutLXtXvrxvBVEGWVpdvRwWbUdh9gQnJS6z5\nZtLzr8cYkET3KO4fabdhZaQYzUFllya7D5dA67O0WfFaaXI/JCSmaBbqD9+e\nq7i4edlg5F5abYLdh4OHVK2vBg3stqlUDPWwqBKcbd4iPdXRc/5l3lA06RJp\nSIj3Hk2PPJOxrODcoiB06txRhzI0oha1jSb7yOYxvs9CQDJlGn6kJ6q8kKve\nGSrQ\r\n=zXMM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","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([str, ]size = 32)`\n\nUtility method for creating a random or hashed salt value. \n\nIf called with a string the string will be hashed, to a generic hash of `size` length.\n\nIf called without any inputs, or with a number, random butes of `size` length will be generated.\n\nThe `salt` can optionally be 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":"34c40591d2ac48202da989ecd56aefd6e0f26f30","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"},"repository":{"url":"git+https://github.com/mafintosh/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.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","@hyperswarm/hypersign":"^0.1.1","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-rc2_1565738494823_0.8596497563379737","host":"s3://npm-registry-packages"}},"2.0.0":{"name":"@hyperswarm/dht","version":"2.0.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@2.0.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"671ba316a5d85899ab3ffc9f985933a9f0ed7ce4","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-2.0.0.tgz","fileCount":18,"integrity":"sha512-mSbOTwA6DX/IVkS8+S0O+tshCv4SxYeDikKOXXwuhbTX1UQ68FDZ4QSMaUcta7xk4dNkrSrI55A1y3x1BJ5G1A==","signatures":[{"sig":"MEUCIGey2T4rgTADoXjf4wt0z32sSsImPwi4wPkQQBSv0UpxAiEAgf8stOKmf7zPlIehVA9Z7PTozpiNYsLKllLbLJ7R3no=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":86478,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdVE4qCRA9TVsSAnZWagAAyosP/2X44E0YIJp8VknY0ujC\nfAhxyAcE2RUzrcUi6C3u63KboFd88mlM2nc06InEjz6iD0rOCghOra1ZSt+J\nM+GC7cqSOziJ2oSL9Z2I8+sfwUriB6BMrR++D2zBxkCs/AsJwVQOPalJki3q\nUX/GS9X7BUtQK/U07/hZIKVn0uMd4u3bIUJjLpC9fY+X8yzpNhpmYQSsasb6\nb7aRAb0uSvFY52EDTE73TbgyyLzE/9oi6Alo3MJa5JtD8RbUOOjkc+aFnGni\nyO80GzBWWuzkt2M879UNgtl0DEFC3bzTJK8qqYpZvIY1c0HhHzE6i1VyLfbQ\nnSGMUd0UlSRq2BtGhEy9KuUnysymTCf/1H+bzA4LYSNAKiyMtRJ1mW7SaIJd\n8aYQcx2NgwFTBZBfZXaKu+E+LKlMr+DBrlgtIQNTxDhi1gZE0/2qkb3M/2d/\nPVH+xaXRAWl1Oov6ZsKhD20a6v4c6AvojcTPbo+qlWmpTeY3cVofET9uE6Rv\nsb+GvMnXqhJB7uY75xZBsH2B21zyPvF/wS8pREunXUsOohu/3brTGxqLQMVb\nnCpk34OgQBhsQmNq/qPnq4TCHiCe0CVRNiMPkZw9s6DVmVH1a7FPY5vIE/Ji\nIaOLeidTpottDCqV5IZI0c0qlmR9Z3IZVllL1f0PEnp2V52jmvX6+8uA2BmI\n0fW8\r\n=+tzU\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"3b5677fd8502db1503f751ae8cfeb38e41346d00","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"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.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,"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_2.0.0_1565806122025_0.37386307121683826","host":"s3://npm-registry-packages"}},"2.1.0":{"name":"@hyperswarm/dht","version":"2.1.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@2.1.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"bc94ea9e79a2593068c94a20d17c8b988c06de16","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-2.1.0.tgz","fileCount":18,"integrity":"sha512-HSHJWt0GOpATM0/AxJUZWAIK4rPtchJimldrj+ZW8ynesbxbmaXZHaZoOQTaKDaUlBW4MAzhxUprlHb0JbaErA==","signatures":[{"sig":"MEYCIQC9iwiukxaOmURNaRRoyxPKNor3Wp92OPuvIxqxLswNaQIhALOSjckFreTg3pfpB04pVO0607v0+Cjg4Fi5fC62fOBq","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85102,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdVFUVCRA9TVsSAnZWagAAoRMP/3dqejWm60smBMDV+PvU\nRtl9IWxYbmtUJ8wWgW5Ca+658tFqXcOlQauqVTJrMwc8ozsEHXPbxitsnU6l\nwYGTClP79HjrJLlcgFI3SGHxfGmTdjpo7J1eUgfHVO70jqn/IUsNSVP1a2a2\n8j2D53swQ6PCTEKT7PM5NR2iH3c7ESLMU7hck5ckExLBhYC+8ws65fV8tNZX\n0tVLHIzruhYrh00Im/TtaUTSiEahpiKtA5vbRfQmZnFm57pYspzqvhXYgapC\nAocjrUATJEBahjPCF+rCNBsQEICt4pZqRmxhLJCns6A94HcuZNzw1TdnkzfW\nHUZTbxFwWTt29gDO4J/C7x+1iaghfxMYeHGfojpTgJ3XzMGcFfmgW7BQxgM4\nj7BXPJn0POUEbsCoVAfxlk/PN3pTw6gzFFkEUZQRwB//jYq4bnB61rDEejFR\nvyX9R7xt4+r+1ImxgpoJiceeyvhVR0jqu2tnaUNZhecAoQoovs7h6/pDcxx7\nIZUOqy1ozbRlCgY6clQp9rIqhlPOcBZzGuFySKwlkv5YcwPACHLelldklfYa\nwQjS16Dg1PiFdT5tmG7jKQhvhw+Opr93gBzTqEZszRzGkU2CPn3vWDiCIqDo\nDxGITcaQy0tQ1/6arvEaz2jhyU7mg2wm2W/SWoMS4SPN2c1usPE870AUzUjU\nOetz\r\n=IqZ4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"b6a676a8a09458b6fcd5ba02cce6c757466422d1","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"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.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","@hyperswarm/hypersign":"^1.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_2.1.0_1565807893447_0.26456973684166707","host":"s3://npm-registry-packages"}},"3.0.0":{"name":"@hyperswarm/dht","version":"3.0.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.0.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"2f18494dbda02c0eaa8721fb91c623033b129f8d","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.0.0.tgz","fileCount":18,"integrity":"sha512-x3fwXtCkyjfevSjNkS2uanEZxGpJ3pcHPHXJN1JuIhQEdRj3L2CYFAGttkWOoT6Mtz19YXvLaf7wI4w6C/68Lg==","signatures":[{"sig":"MEYCIQCiM+PFzmI6BlZLogVyjc91akRhIJK1MawdlkhQmbAregIhANhDoPP3V60h6zuDDbjFuswT0XKFV1qZ7C+1xnh7HgKA","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85094,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdZ9MiCRA9TVsSAnZWagAAEnEP/AgEPl9Vmb6GlLjEiSAA\nqnV/5Os6uoyPNtaIfDzC2B5izq28pxGD1N5dRYudcCm8l0sHGhlL2Mkqx55u\nLCBDo6OAvr/gwRKJM4ukIbTzIWFgl64rhqCGIK+h5OtRLaKzmlR+U0ZopWBC\n72JINZAr/YWEYEJEkgE/G0/jeDrDGqzBrk18EGfsGmQ3sBv4CToMxfcWa+M7\non9FBp1XxAL0OI5YdKTER7qS8OwiEjL9SSc33gB9c1Bwv29cKffmU+33m6oL\n02M3tXNE9RXR2qPYR4txY7flxgmGswkge+dvKYlACOo3x5ZsbaHnQi2Jy3i2\nRNmU8ZwCB9WuZ5v0GbaFS6vvtZjSoC3wN+Lk8o+9ujYram1tX2PNc7+7yE52\nhZfBJ5Dh3OqK/drpLci3v+LD/2/zAWadq6EqhaZz8odXPRZOIAzFi7HvriJe\nrjF18Am4Ua+JtuPXDSTJ3i/LEI8A+PVN/+mgN2JgjRQecD2Fyg9pKh+hCc69\nBCRpPzQ9kdqoZxT/DqZ1feWGkN0vH1KQ4Tf755AZ4cMtDobryBQF/76+GaGx\nZzssaZYHulW/gUr/39dmHunNolUHtkW+UEJ0V2eMXCpbUZzQoO3f0N0do8Ec\npQg5fynd7bpyc4C9EbvwVMFzMWG1ifxMgLWHyx+sbM+eBUf8RMu/q9qbW0oz\n6nIK\r\n=Ph1S\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"c338bdbba39632aaeec22eb7c5b7c927011004e1","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"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.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","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.0.0_1567085345974_0.20294051210617092","host":"s3://npm-registry-packages"}},"3.0.1":{"name":"@hyperswarm/dht","version":"3.0.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.0.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"e0961dfdde17fec072e3cf094154cfdf741f8b73","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.0.1.tgz","fileCount":18,"integrity":"sha512-sYdtctAX1zB6aZN4lvsaV8QCaHLrqicoPzo4QHYvn/ioltXfOMuqq58M1O0M3+QUnUPxfR5MHJS7HSZlsCu/QQ==","signatures":[{"sig":"MEYCIQD/DC45RCAfzlbvcHuv/nZ5OJGNYLK8BzqHuDqi8AnS1AIhAPCnCxZrrj4OUeLlKZziOubguvq3snIVmBYVvQvMkwtB","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":85960,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdqOKBCRA9TVsSAnZWagAAUSUP/0AE/Y/sXtV+esfPjh6R\n1wCbm/MVaWs1bpC+OgvCMYtiom+jiVCGeLm/ySt2RArDwOkRiEDzcL8BP1w3\nElmDicuEeG1KHXT+3/CQlySCa3ZxizandQVL1w+ZTKezF1f1x+3uu6AGxhN0\nxfWXbg+GqOsJlHjSGqEW/j5E3m31bKkIYqzn4To5PzScH4lRNbKcFg5rk5Gt\nShYqLtX8FgDZ3RzXcXGZCR9iVToS2+SgsDgUBG9uycPiEdXcpTdNuZD7GnvA\noqve8QgPyLSWjsMv0MdsZaqiXaoYdKXGg1/lysn72y5/1QVRRqnWJzxYHJpQ\n6q2jgyxlnG/4T6Hs8TGAGgnwpNTTUJequCvEVo0P9KFWYcfOx+BFWB1ZT98Y\nJ+tJ9FdPqNfsazWN3ouAzbr3TPf0punsrjeOJ8/hKiOUu5MRqYPvKN4xahhX\n/TmFZPdwgXc67mDEeH4bvkI5wiAw1YLo25K/N/hZqXP8x7yxyCNPeHIujxIS\nLOyLbzU+xFIbtKWVAKh/hTDUASm3zqi/CD6rs1okZbevGycV6IqJOn9XpVIv\nnqgid7NRBQnYAe0InGUJVBoJfPyrF1WPGuo/R0/10ozR3yqAUsa7Uvn0Ja6s\nPYYosOmpBfTgmt3a0HQHpYx4XrXKAfc2jnhC7tk0G9/WXGDB689XjbquRYNU\nrhmo\r\n=bWRL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"47265ad2ba702ccbf95cd5ed273a4ebf14394eaf","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":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.16.3","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","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.0.1_1571349120640_0.36302768464742297","host":"s3://npm-registry-packages"}},"3.1.0":{"name":"@hyperswarm/dht","version":"3.1.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.1.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"fdea415f91cfdb0726665310b5af7c69b3769903","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.1.0.tgz","fileCount":18,"integrity":"sha512-zlDenk1fjmCobR9HrpY5rkQeCZ2wphR6qc8NQ4xZaNga6pHo2gYvrp7SsNAKApzKEdD74mrwVqMGy+Ntae+8/g==","signatures":[{"sig":"MEUCIHoBgoHbDskuz3jSexTzdWxBSbwYrgcJajBQQE6wHEHTAiEAivNGs+t08gg0eBFSn/gcOESYGAohuLdA7squtu6JWiM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":89417,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd4YbVCRA9TVsSAnZWagAAg6gP/2O8UKePJ30CLJ4mI6HZ\nYrPfqt1KDJowJtNI3XThs4KCH6ZfYnt0IooWkIRWOWwbqIDRmLnEyJLHm/Hu\nB+pMYzw3oZuHkTtgP+9jK7cIsV9a3YQxTPdyjQF8Jwnx+rjMGgjYDV8t6kdB\npD4kZH2sjmw2o2m0WGFulPxyi3/sHF8vyOHsLZuv5R3fmmi2e7PD6iC0nw3F\nXPTqUbVJMFZVqR1Mughda0pAini0x/Pg2CXL2qF/LYlSb/Wj4tVuhxbQJ+L3\nvAw+tbpwgMw+DBhCA4h6nZUGMBQb7Hx7vPS0uu5Y9U2LBjsuPgx7fWRbaqOa\nXLdw+sGl8ImCWcsuqAZnjXiKXDb8OkIfGwdc2sAAKPV5rYR4aA06oC+BXFD8\n6op/Jx8kabPL4Aw+Mh9wiD9hebX0gRVGj1oCCmgWjsZaC8nMo/gMXMmgtN0v\nxqYfhvjJU99rEFtiWThCPBsLywMrHRtbeeMX5AATyo5EqM6Ko2phCFr+Lj1x\nVhpVxzjEHXK5o9UptUVm1HcAOuUrlYIz9WXkiEMmBu2FAdJ7C/sJyiYxmoZv\neswPXHvrJMZvyWOhRcgkF00TqN9LXzbGLGXxkFVSx9W2IBZYH0L2IaAk4GpS\nC54tZW8uiAgROepZaaUvHMH/vHDk4RNXMFoiqBDoiqej8UywZZAcMkswkqMx\nrs9/\r\n=AJal\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"23630b1c2d9a42f5513025af7160e8a8524b2214","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"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.16.3","dependencies":{"dht-rpc":"^4.2.0","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","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.1.0_1575061205126_0.6979505856774464","host":"s3://npm-registry-packages"}},"3.1.1":{"name":"@hyperswarm/dht","version":"3.1.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.1.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"./bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"e8fbdd188c63dd6001b68b8b894a0cc04c28dc6d","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.1.1.tgz","fileCount":18,"integrity":"sha512-Hk4N6W6uM6lCj/38cYydfGVAu0YsJ5kCr1/FTH6e4BoMvXs8F03HKGYBNXKaTEU+dhH2sF/mCBDGPICUdpOcpw==","signatures":[{"sig":"MEUCIE2NygwJszIqv+FpVOzQMginkPFtjgZOBYwNF0yvFs3IAiEA6JSCpJhcQR13jB8E3TPbpnS0eyTM1pvI3CTPLpOmukM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":89460,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd53fUCRA9TVsSAnZWagAA4o4P/jtlwylNqUPgo6MB+g+0\nmWjAYVVxMjhCB4dEQX6H8itxCCGt9yQd7mlp0cQy2sUVmuVLXftHGw0YcW6g\nWM07wnHrSuObkmzQQzQSxsFqRzBpq9QCGjPHDMtl8HxhfXCFR9pUrU3iWc7q\nmC9FhDDVAjlg61d5Nbk71sS9bdmfEI0lhicafVHMvT39rf86ev+n5nLCDRkU\ndYxqchQl2JIRrlyc4oiY/nETH7F59QpyFOsWwb5a0Qbny0fhoaDjfVCdsTDP\n6HYXAu6LWpMbVFtNLmQro8zA2Y5h5UZhC5wqeLWie/p/TbkVK8ipn6QPTY6g\n7+eSp7QLOyeBv8U8C4E+gUygGJ5HgFSHIN7YwDEWOxLnNhilvL6vx6cNXBZo\n/uO1LG6ubzZkJDa8hUeUELIDZhmf28DZ+DBPWCF/kn2RGABkt54ozBTuz5n2\nZuiAQ9J4cqffvBBUG2Ieu+Olo2IFTP/xKSEKczknb0Uhi4keDgqvD6hJrSLQ\nhcegzLU9D2CiLnpnw/4JBPokm8CDVGilSYMpUsBXrxyOjRFCohZf1MZQhwiB\n1Gmv1MFgABEs8A3jKRQIUJP5hoF5q97BeB92HoXmg/2cqeuu3i+YDg44Yfkk\nowNAa3QDmOIQZ9uf5AefFwmfBrG+ifXGfYNEqT++YiWLq64gJFZq/WkIH/tB\n7dHH\r\n=klur\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"042bd20dff92f16c609189a1b9340411172f0aef","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"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.9.0","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"10.16.3","dependencies":{"dht-rpc":"^4.2.0","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","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.1.1_1575450579507_0.6120196244123113","host":"s3://npm-registry-packages"}},"3.1.2":{"name":"@hyperswarm/dht","version":"3.1.2","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.1.2","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"af9ffd7d8bca8e73e6617e22baf8c806d69a2698","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.1.2.tgz","fileCount":18,"integrity":"sha512-W4WZzCCDij7yTHIjc1HmvCbPWNR/thwGaP64pGgReU+zgxzo8H+yzBXr35vUn9XkerTxmrH2HsWFhhVXyQ6mnA==","signatures":[{"sig":"MEQCICGm6rBDWdC8Ga7TIl8B3YNpemQGiaUKGdjw6U/cqXTlAiBtdtNBH6Kewl3l0mBbykIMQ5dPWG5mpTB1vElX/x0HNA==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":89541,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeHuh7CRA9TVsSAnZWagAA7WoP/Aqn2u9y1Xp1bwmmu23I\ncatH0lP14zxMF1xtaomFZdBp9vhh53HNzByFW88ksHgOBW5siISE+ipd6t6a\nUCpYVBtgTpc0BjXXGXbeV9Bs+1pykh4IIwTGgdF9L82s+/GJ/SL8DQI+n+d+\nbrLP7IJTe89uUu0UmGUkjZbJIVn14ukF4OQa97NPoOQh9WLs707dds5OUNHj\nUM8Sz2ohQyBFf1v1wGRVgQUXp8xBTzV9HU9ttPuKT5HK3gqtUJzKnqgnCe5h\nfZCre4TlXQpGKq+tqZ+Ovj4lCJqGmF3+mC+RJN0QaCsG6UpOlD/zFzUSbmKA\nDDpWqmsCrpiXpCQDIgvccAjUd//pvkNYkrCSxWRsmJp82FQejFqTMIAkpfnc\nPXI8mm75XBw7xl97HJ7nysJvttyt9cnDZKuszoUIdbVI9MRyeKqtubTh/3tE\noryIps+evgr2BEUK+oNqjWEX5ZfbM0sPfvgwegTpu2on7hUcrawpXrmypX0w\nJ3hXPNJBQEVpLPeymQcWgR1SNePth4mHJhnjhd1GRnm/MJ1zkK2/F+976lvD\ngGVSE+97afzuQ3d/PISwnLQydXeBXEUW5WBlWstsOfMLVOT6e2H1sHmmd4nC\n6vkboc883BEEQJuTVeR4MXGuikzDTPU+wYRfakhUKOu+22dOg7NA8FLpucTJ\nARv4\r\n=3AAD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"275b4895c9270ac8f85ad73eec9175b5ef00a78a","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":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.14.1","dependencies":{"dht-rpc":"^4.2.0","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","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.1.2_1579083898523_0.3303209677367849","host":"s3://npm-registry-packages"}},"3.2.0":{"name":"@hyperswarm/dht","version":"3.2.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.2.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"nyc":{"exclude":["messages.js","**/test/**"]},"dist":{"shasum":"2195d31f967a59cee69a46c523cb9e8d9abf4e66","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.2.0.tgz","fileCount":18,"integrity":"sha512-0v8gZczHlj6o9piUDz/UEF9VO+KQTW5yigXIHixWGVUmnugXNY/T29INyvP1Cb8c4kC7fNOv7xBLFIQ9nnMZOQ==","signatures":[{"sig":"MEUCICFvkHnwQky9kiO6RsJh8e34fRo894HowiN4GD4JtnEvAiEA8CvoGF+NMnWl7I7CR0lA+5oRJfBTwv6dD1PntAmopvI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":89579,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeS/+9CRA9TVsSAnZWagAAw+gP/2z3xdfbVMyu9+CVn6Js\nYubUA/s0juNOyH5cBQPqg+y1YJFL023Zct4P+WpYfYqAp4JJCBrdfOlcEpfb\nqQfWRh8hXM0P0Eb2KMnytf+8M8RfgJsEvI5txGENKJmRh0krLbIoF2cxFQqn\n2qa1mDTfLtYltnLwObcBVHfdH7Xs1f7VTAgEzNeX7kcZBCuSpMjMgJKT6qT8\nBcVBwKrmfKlxP6LFfhBAaRF4aKc/cLcAYuS83lTX+hSJmuCndZKhwZrmiabg\nrAknLoxUvjSLI2wkuTbgMN4obpr8H/sAMqKbMGMjOpwizGz7TeVXRLbL+HK9\n8h/ZC9PbAi+F1A6lp4R4tHXxaPQTCP39i1SLs5a7pl+biD2c4Dcx6257YU53\nEsMDQYg22TZIRdrZEZvuU2NBfJbrL4gFlX0jBfp1ZJu7hmNklTwUVQ9pNXTR\nHjOMcsLUorAHFjNyBiW1M/lelMIAs4x7XkMnEJTH1JtFZ9kDKYzeO6eYbzGd\nOhf2K/gWPV+3Wauy/tpSD0/D/1MP5N42PXrwMULM1U0+TqznyaSkmPtS801v\nEWhp6wczlB5nE/j767tVjG1Em04stxRT3+v14Yufr+hOJesslEiEOqoYRkJT\n4CqA7hE1En/CItamOigdIVTmtBTqq6Q5D14+bQiMoEr8XOT3dfughvIubnPX\nMEjH\r\n=vkp/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"0ab93930f8ee77ba36571a35a5f8c954c171f455","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":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.14.1","dependencies":{"dht-rpc":"^4.2.0","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","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.2.0_1582038973157_0.15352963488103977","host":"s3://npm-registry-packages"}},"3.3.0":{"name":"@hyperswarm/dht","version":"3.3.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.3.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"557666ab2af0a5738ae627502be6bab78f47d238","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.3.0.tgz","fileCount":20,"integrity":"sha512-BMyhRQq5py5tzU2JxjQUpHWoL62ZBQ7y+EtQg90VXbrPFrZh3dRO22k52UmEOR+jUGj3EEE1qtUxYbLi4kfSNA==","signatures":[{"sig":"MEYCIQDCZhP4IRPRIajst8kRLYQcHjMosmZxdWtIREPX+0i48gIhAPHumNq7OTb3jszatMMOAXKkAclg0kZlBoFJotXxCua9","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeWSGpCRA9TVsSAnZWagAAB/4P/R87xLA0zfSHYj10mbJm\n5/UXNASawdgioeq95MptuLTU9SNmexWjwhw7QCQ5YFfr/b8qzeDHTQ2RXeAM\n1esI5CwZI5w6XVpqKn3zO3S8lSrcyxSHjcVACZ+eden4JhneBF7g35mfz7dG\nLVfjGsw0+GKdHQSmirUTQPzi2/a8gsc8WHBoIzdJrOAKO2NecN2oxY+94gcW\neK+FBz4MPCZ8epiWA0UPoY6Anm4HaW4tgcuJdZ1GUPkrj4sS85RznYjG4Nos\nxcK9TjwZhIY66GWF4doPyDttQ6mGnFJX2wiiDl918c93DB4RXn4FEI9fJ4VW\ndFlBpObQWVqt4fmBJP7FzvE5evwF7wOwiwnb/JH35tPl+l7Y8B4+/ILGpbTj\nEBAL4ylWs1vF2x3HKiFqImH4jY21j5ed0Qtb+Kubb/0QQcvJnUHVHIf0A0cE\nY6yYcCeLdZfP7tC94ZXDRnQ08N3fnQ41LCkTctmOs1DNtaA6epF51ov4qJYk\nn+VZ9gjE+ZQyMtsSkR7ewkMiaY2aMqIJq30g5iCPf4EsaHHYRLiIw2+UoBaP\nK1+ExHJCIua1McNWzXinzAkM5Bx6ts/otnCsh5GRCzL4jDnVMRF1j5OomehT\n5BXXLgeTrlwGUQCQJJRlezcD0lT5cQcQ599ihVFpTyUT8zxinnMpc82645Jo\nTKr9\r\n=7SA6\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"054605006bcabcedd142c28746dd3e9c4ed92315","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.16.1","dependencies":{"dht-rpc":"^4.7.0","hashlru":"^2.3.0","ipv4-peers":"^2.0.0","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.3.0_1582899625000_0.7674978275941047","host":"s3://npm-registry-packages"}},"3.4.0":{"name":"@hyperswarm/dht","version":"3.4.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.4.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"9405c410f4f235104d6c63baafe6a917c4a879c6","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.4.0.tgz","fileCount":20,"integrity":"sha512-Tasad/r6t0R/ImyrZSIyNlAmbpI2KQncGrEJjm4x2XkntziS0wkwWLbW1Ka66zmUkS9fKVPRrqYFllJ6K4lQ7w==","signatures":[{"sig":"MEYCIQCu8c2y5oSoo/6qsegaFBBwdk4OFcxTZuNQ2gWqoQZSOgIhAN/AYyzIgWbDaSuSgzH249vjVvnorlbAkgPlEMYFNNXv","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":97675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeWS9QCRA9TVsSAnZWagAAykYP/2sN+8fwzPWCTbr2iK3f\nEoOGXtCLUiiq9/S0JtiQe1EZMU4xP3sJQUCAnHnHUCYbxmkpa7eoL8humbCv\n6xpBvO985XPrzNsu4lhht6OJy4XZb5y4LT5r96dbQ67sdV04dXLTV5yjA6u2\n0RFCdsPywVDmrQEx8HR8vMwxZOIvi3zqi/vVycRrWEFLGsKDn9gVAQCbanF9\n4y4tsSF/4XAkBehggIR3e+NVzElael2Ab/cbN+uK63uSUnq7t/z6f0XqVIPC\n+ZNANFSqmEtKpq1KGD/DMpXAGqmCyCh2uaY4YA7FSPdXhGKJaryetUCnbK93\nBrFBDCcdh4hO2FHBIYS2N/kZlX7x3Glt1Wy3SpujFDJBwjfoaoC6vQvZzohm\nLCZul73qmrgH3cJCEyIvFMkfARX5biSPe7mgFBoL+x7DwBy/eBx82An36a1P\n9Zn8s3ecL0ZPDA02khgwTuRaDWmrxjGCKD7W6VTQcMsIxsOYuquklt2C40Pl\nQN9Kzr6lvC36cJeesHc4USiqR/TSbmXU0oKr6nC2+YUVZEuFUm63OEHayz/J\nwAL45FtyxmOyiuTa/GTg/CJtmxUFaaz7Wq2V4ClTVsId6I1gD6qWTb+38mGy\ngTMrR6/36k578/iDrV53q+zGRS0xFjzjm/8rkhFTC/JKY6JsghwQvazbdf6X\neM7a\r\n=IFj8\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"12ac06b6b004aae2ffae6153e3b54a70da652123","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.14.0","dependencies":{"dht-rpc":"^4.7.0","hashlru":"^2.3.0","ipv4-peers":"^2.0.0","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.4.0_1582903120323_0.3856917060521783","host":"s3://npm-registry-packages"}},"3.5.0":{"name":"@hyperswarm/dht","version":"3.5.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.5.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"93a18363b10c631b8a67b12caef32c6e4847a8de","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.5.0.tgz","fileCount":21,"integrity":"sha512-4VEl4lVuYMrY6TmfV2EquR1BKgbOy50vrbpHHkiiTzK3byRvDDTD8PGckHzf7DygiJIRROpMxfIUZP1aj8gJ3w==","signatures":[{"sig":"MEUCIBpLXqLju04AW6jwN7erOSDTOL/TyTkolTqRMnhMeDgOAiEApjKYS8b2HSVS7xZEEJ5DITGwhwWttJ3cspNm2BUvdek=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":102591,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJehj6OCRA9TVsSAnZWagAAow8P/jXWl/V4dpjEbDOyEbMT\n0tCHANqocvRFUHlsYBsGamNz6+PSCY5cwY2s3G2flcMnCAvtS+sY/dhyS29i\nYpIfQt5LRiCPSzyil5SYFOZPnN7SUBrJt5VXDDja6Fw/dl6bfOwC6lnnYG57\nKi6DLFMa9mphCcG0hX/SFXqx9UHBayfnaxkCowqIBZ7HPstnNuTAapjj7Iuf\n8LaWMwfec0LrAW48jCEvnRZjD9wz9KBRUJQ+rdLan8O1osoMacG1INAOLHBW\nCvS5QE5kC940sLfh4tPdPrHa0bRfZF1nnbBKEV+YeX961pLoZjBVvByOgrYb\nYg006CHX8E6AHquGYFFCppnmuD8WSaMExgb1nzE7mbGfb8V47hW8KhfOqiy9\nHXdEjvZpmeXWCjM5dUMdIfjD3xbmZfdtldcLxh8Lw1AvnhMVnJInIbGFHG4a\nPdvQdcCkUjMPkUPuATF4dw2t5reBgStaUvfLSvTGXWoeuS/RilZ7n+zrj9ht\n4qsUPyBJCwvOglc3VQAMXOHS9ZT9TrecAVCS/zN+m2/EKtuZl/K0YEVTgAlJ\naGrl0dfrs2jtlmUcLy9FK5BDgwrCKF+36LtZn8eChBwyXAl2dVytjwx82jdk\niaJyiAGysCj1lDFP8/btE+v5dW/gLcppDkfBaQgxB4s0/c5aBiLlZq5obocL\nJm+K\r\n=4evL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"39fad507b632d554ed9ed7d32b032b1adf8320f3","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.7","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"13.9.0","dependencies":{"dht-rpc":"^4.7.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.5.0_1585856142078_0.1197512601435391","host":"s3://npm-registry-packages"}},"3.5.1":{"name":"@hyperswarm/dht","version":"3.5.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.5.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"31305cf5cd60135c454b536333a39e0227ee98a4","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.5.1.tgz","fileCount":21,"integrity":"sha512-8g/nIr8C4LSEh4MCwWive2P6dKS6VrTJGIJSSQX4MQqDz3blK0C2Le+K22O2J2D5SwqjGIPtDmvKlzbwNohhVg==","signatures":[{"sig":"MEUCIQDFi93ZbFyV2L05mXdrjdVU7M/iOQFV2el+NWwSTXuzKQIgYIY89AlQhXFZPMfl0jLa5oXvo8Qc8N1p76wxB725Gfc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":102675,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJehkRwCRA9TVsSAnZWagAAAFUP/1fxPQCqmhnU8drDiRBX\njITuMYy+sWNOH604f0nYWORJ8EPSMRWKPOjuUTm2Qvmu6PUqNRlANozzeaw9\nD9ldDNayeB/LQMpORGVsP1JmIJkFDAMIX3HbPHAuLfEa04RrQClG8XqKUo0w\n2G0FGivlPAeDxywQMpfy7AK0qiQ57wrCNsN7nMmRJ+S0UZPUzBhs7IyuXLC9\nJh8kuWTO+Z9fdYp/bWhW6QctN2ctTglW2jso26XT+mocOdtkNOOdX/q7eRfV\nfo8+OtY2mIKGSZl72oTKscjFgR8jn+JAm5JjkmAl7gcAceVMMmwm34ocOwmX\nLUOF69dAjQcB7UrLYXZJKReCN0sPC+/MhT69uQ1TKupbVNd65q9d2cKt+1Qk\nTQhcWeJf9qShrV5LpgzC1bjIXdIPj0Pm1U4maX9mD3ENOJgIDQIthGeaNZJR\nDA4N6i825Wx1deai1d6p+N/8wr1O11VHemKVJ+YEjpMefqqp84Qcdgmli1yP\nLBPcIT6wpe+z8jfLQVOx7Yd/lrRVRTevzOn2Xmr6hK/QQbRlGTrhJsPfU8LA\nUxSp1UfdqZo9KocfAzPqXdYGQVMKVJjHcPSImT6hbdPXZySj5Brqnz9crgEj\nTbLRiJY7I6WbWcsn5FRdJrUqm9vP6HI8x5T66Ni4qh9AEnpS0ixW5eYi6UXp\njnkw\r\n=f+v3\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"eceb0f7e2142cdb930c19539fa1253b8f2233f83","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.7","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"13.9.0","dependencies":{"dht-rpc":"^4.7.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.5.1_1585857647975_0.8454258789025835","host":"s3://npm-registry-packages"}},"3.5.2":{"name":"@hyperswarm/dht","version":"3.5.2","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.5.2","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"d59d770156d6c6eb542c60bd8b7dfe13f1a0b43e","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.5.2.tgz","fileCount":21,"integrity":"sha512-WMea24RGEDIZYv48rJw60OKaqxER282WmdmbT+CRe7IimNQIZruYLly0lgnC9ZJhhup0WpFSmeh0m6ZEmnMVkg==","signatures":[{"sig":"MEQCIBC4XiPM+1goYTj4YaWwQzprbwsjNZGQDPuF0/AjQu1lAiBCacF3kWs+B9rCSYLsUW/3DUcPVa90IMhSZSu1rllt0Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103937,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJehlneCRA9TVsSAnZWagAAsN4P/3X1i4MDMrjfUuRToIR/\n5dqrkzvyYcXtsIzP4O+1QJ0ddpO8t2dJZjkNIG/LOyZZgDvvTCSZdEwQ+Ou0\niMjN9nPOE/+xyiQj++snaL5FYMx7oHSPDS+RC+uDpvR67ueW73eH/LMLCVgV\nYiTkA21Z07oQZ4NabC+4Vvs6i8osJY9lqlB6UOp9hjtglE2coBoPL/po1nmz\np0bzq6dOUb+OuqWLMMdQVzW08Ub67roF6Dj76JCJUhgR9syEXz4irR3xabug\nfBHfWDNE+cuctpqpNPIbdV0fiSvMD39RsFC2zda7fHM4tlsaw8+1ycF9hf8K\nnVOADkmQM+gjEOxS6TxvAvvQkY8esF6nU6ao55bZDgu4d0SNPpFgoJfz2a5s\nB/AxviX789ViNdDLO+Lw+bUjHQHXc7zWyzKTdQuHqiIXQZYXEd9j/83cvLMF\nO3HiDdifuxZWkpY1a7JTit1yfdFuS3I/7zHc5vtlTyLfiPNMYf4l5MrMWAVa\n0PNRDOTY3rqoCTY1DHFSveZXc7qr0+UInCXcgsGR/QdXBZ61JzPlsqlkf1Tv\nJNX0voBAYkKIFc7Pkt/EIcRz2SgIk+iiedhUFKD2trMbrjUf0ugodMfFiSPz\nysz5B8+hYT8aaUmY5WNQGzOqbWikztQWeOW74KoR8UR3J7hYEqSsLiavag/C\nZvtB\r\n=LYYz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"b21c6951f2ba1f3ad1b95404fb369253bc490214","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.7","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"13.9.0","dependencies":{"dht-rpc":"^4.7.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.5.2_1585863134203_0.4352981541555587","host":"s3://npm-registry-packages"}},"3.6.0":{"name":"@hyperswarm/dht","version":"3.6.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.6.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"84f8abf2e1ac9f02daba5bd574106e9515872e6d","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.6.0.tgz","fileCount":21,"integrity":"sha512-ioS1ZUwVfG3042jQMk620zqnspto8FHbXjcF+V5bMqtJ5nlscfU9QQGsF+JRmczMkFA+GXt/yIHWtAkXsPqlHA==","signatures":[{"sig":"MEQCIAbuO57WaUbpS12UxvW+Y2na0CvOVv6U14U0R7KFKjI8AiBG+z6ESmKj+r4KUw3PSi/srvG1ALaizHE8a1ulwBioGg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":104310,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemv3pCRA9TVsSAnZWagAAtIoP/0SWuJEJ9vpuw6PlCmVO\nsfTuVgKmutwxAoROMyild/9R6ivLpawCfZ1hSvuqRquBrXlP+jHuijGnitZI\nYIe41QGqAKXvM0ZDEb4HObJjnIJS+uwunK+pCWmrGbcapQ1JYlXV6WPy2Jry\n1wzUEXHO72NEEU2ZsMXNUeFLEuS4w9ktC3vjQa8tqYdFIlSd7mfS0tmYILej\nCLHt2CgtJrXtFSCzSq0nTkQZiWv50omj/EbfsWcHQNap+SfwRKSAU2ppVgas\nLzKuUVq831854ZvuurVRSs+2W0/3HnV2UABhyCNA8Y2Af1Mqtl0y0Hxsi7ux\no009zseduwoYsREl28x1cx+Pn+M+Eqy0l0yJc7gr9pTLl42K+6F0jbCfBOG3\nl6BySM243bYJDOHubNepGOsGBVHtcl1Pjzyw0ZJZsWIMiorKdSYrx0Ihu9z2\nKW6YHnt17Y40S4bvnRt7nFjyfR36edn6S3FytEIlddEHwLdAMA6wO9YIMqBy\nqg2y//kt9A0hyxYvMesGQCFDrIiTYENgDHBxCI3PUqeZMPa3Z2aDRNqVOsa3\ngEsMdo25YR4Nbv5LvIHdnnnv+94PFsj8q4djtVU7UxF+KnYRwusa8LK2Gbmp\nAsP8MVPlwKy0POGUOA8jnsGcc/wR1TKEcFnpMZ3UOUdUovqsal/NvfIityEJ\nt7ao\r\n=j6nM\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"f4b98097f4724b128660a00656182dd60b6a0220","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.7","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"13.9.0","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.6.0_1587215848980_0.8465685582720706","host":"s3://npm-registry-packages"}},"3.6.1":{"name":"@hyperswarm/dht","version":"3.6.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.6.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"56f397b1ed17ae8071c3f3f77a8817b0dfb29c23","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.6.1.tgz","fileCount":21,"integrity":"sha512-cPzS06vy7Oe4biCUIhXXUW6tQDCZZmJr2NCg6tfa/trlkWnPEkt+GQChsUQ+dty21kQPNQU3Typ/IJqVEax6gA==","signatures":[{"sig":"MEUCIQC5I/0+vMYTtg0DuMd9HNMoKn+1hL6kOt0puIDvihHx6QIgCLpzYh5yKiOq4GAhLYc2KtW6yNlwPZFBbzrvNcceBrM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":104315,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemv58CRA9TVsSAnZWagAAUHwP/Rbc7BsypZg1oqAza16j\n5uUslWdgIfqN9DVm6aPPLzaWs/v+ycTjhEPPWQLl7xI9HcCvNpLtwgUZB5wR\nX5TTQxzdkoUojRRtFeTu757uANtkTLmDOFxTRdcHP2fi66JVQKkyTR4Jt1s1\n4Shkr9QSW01h0FiFpTHKIcMYE0M4sfla/RY9F9CPJ/imM/hNkj9919BWBS6o\nwNMpXdF7w+z/yzx67FNEiIwkqR/5PPfw8D6hsZQU4X9iH6xZbt45wVF/sqPe\n3f7Tb20w3NXtkN52siUabDpOgAkH0YhSyMgQYOH19y+jcFiWqywZ943u1/Xe\nSnHIKay7RFDK4oe5uPychuw6F3cmPjbH74/ARHE53O5iALoDfIQthRCZcwFO\n+pRNM/oLqIb7XzknX1B42zuaWn6s5b20z6D8dDxH33mHNbuofxUQKIqG23c2\nQrkEufRk2NRPf9VRz75WEsNvUVWWXDOjnyusVUmau1p7Q9MB89x+h7dYd6TW\nKyW/ZYP5Jv1MQcn3BwiM6fPYVp1atg9Fa+vRtrCeOWNAkz6AaoVT4Jup6VBj\nWubv9/9f4426ObIac7gLExgQKPhbyWRvWqnYQ4S4h7qAiQ/pT1gD/DYboeDl\nVGo4Dw5l74XjvCeoIO06Y+GWJ3FYf5m1tywYAvi6vj5F2yMGkyr5p824zY6y\nMbo3\r\n=V9xR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"2ab1e12ef64feb488d66352a3115765e478f6e23","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.7","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"13.9.0","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^1.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.6.1_1587215996395_0.7154014123763728","host":"s3://npm-registry-packages"}},"3.6.2":{"name":"@hyperswarm/dht","version":"3.6.2","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.6.2","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"9f90eb1c81d348d17585b638acbec278ea610ac3","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.6.2.tgz","fileCount":21,"integrity":"sha512-mqKg6TgnOpQ+C8I6CYEPw3TPek4ORdsUhQzEuNIKm7SMB+3zQd8f6rkjmzDIM0IRFnGwZ2NcdCtvuYWFlXUTYg==","signatures":[{"sig":"MEUCIQDKyBm5dym5NjmpveetE0GdL1wKWUFyLNNlHf5CRtcRdwIgSNWpnrC/7kdZnw6naBxrmh8kZu/PtlTrLvixkLnAPPM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":104542,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJemz6DCRA9TVsSAnZWagAArUQQAIwCsUBpVCb5lSqW495m\npepoLu6Jj27JMDvWfJkWXWZAtSrRgcb5A1DKKjO3sTh9zTAFvnf4+NW3zAOn\no6j4hTOETK+6wqoPoEi7pXY8WJ8CNlrQI/0iO2Af2rsSqyh8KIMx2/nOICNy\nVm49+w3KGdyqt7VfZdwjiFflji6rkrAVctrZ17W6VfjRvvXzo86sMPeTsfpP\n9wNB/kmfe2jEEK1G9hvvhIM290kjlx/MzIU3wqGXtu3qXhUwepZTFiasBd3l\n4cX0q6lZ+dpq4yGKzrEyPgjPBsd5cxFPvyvAY1n3jbz4rxS3kHL0sL8ZUbew\niMszCBsmpsiZYMvIHhLoBX/m3MqUYWMQ5aVI3jA3wXQn5FZEOOS/mO3ohmlO\nwUCJtzEcboJ9pN7h95myQ/YZPc+YNwUsIUDRmrLpZew1FTC7DXVvtuYUSRxf\nPJCw/xavcAtQ7p3xP3jD32cG6wEUzI1Stg95g/kWznX2qDLHD2w9wWUd1JjH\nyJ2PRKTA3zaFp9huWNIzvzcp1VyFUikru0rZxoAUuf2A+Nyf0NExfzF5DquX\n+csPCLz2s52Pm/TuzqkHoXIWDFZ3yC7GQVsmlixJuaBVBBwAdoQ8afWN3Qks\nU9lUNLJV1xxIhEjvcpy0GnrHt73fH2msJWuuEgywgX1bbhUn5NT3v2MYYm8X\nR9+T\r\n=OT4n\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"cf82b6aeca49fd769333ee4979203b321927b753","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.13.7","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"13.9.0","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^2.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.6.2_1587232387429_0.8021623891300518","host":"s3://npm-registry-packages"}},"3.6.3":{"name":"@hyperswarm/dht","version":"3.6.3","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.6.3","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"e498707a565308c730d5f20c96d10b3cd8458c9c","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.6.3.tgz","fileCount":20,"integrity":"sha512-ft+kjZK6YfxMZQ1rLVEKPug8ClesRbmSDBMY08N0h8LpBZ9ewHLPtf1W3rPeInPJQzcp3vLPHtX/YTngzNZbrA==","signatures":[{"sig":"MEYCIQC9J2KpCamW5O/DPnjXwot2DPKInAG1GlSMGIzXCqDRwQIhAIWhgupMLbRXJu77i6g8AFERugU8ErZVzGFUrJnQkS8b","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103709,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeoJhiCRA9TVsSAnZWagAAjlkQAKImIMyVymwUB6EuinFc\nsTjNsg1QPFrfQ0KfwqUMbnc71lACdL3FQZLmNQ7Rx0iGl46sfHxw++SZvV3x\nkeOM4TOwqLoySzF9ciT7lFMi0x22eW6UnoJoyrRuX8uIcCzAdAPoqi+KGX5Q\n2CNv+Z7NZumBSPcCf/a5B5Ujka43JgCo5lncliTasnzueF6Zg+u6wNufJg68\nhh7T55qGDUo3zgtaXXZtHNhHhvPFx1U5V1QV1rGj8KfXKQwat8wKBDgHBJiY\nqXSKXRA5KKT2C43VbgyKpyJH3HtLr33MyShtPieHTnCZuUnqrTaUHKipPWc9\nuXu8IJOWdndaJHxSFl9Npbl7b9e/ChNic84+DArgEqX3YcUbwuN+dosQZ0pL\nZPZ4tPMijlU88TWUf+d9ZfUDwRJ3550Ko0yyMVTzRwwhsvjXcm3WWiDQzGEl\nhVKlyt5DS46/xwCuTF9XFEvLyU8roA0gTnV5tIMCmlaR+l7B/ji8gOw7ZZlD\nsM99x4xlrkNKXUthlKc0Rr35e8JKNnIxZf4+gxCwsMfFiVhgaGEFGB7dDjwk\nmdIYtP02fr6NBe1bZn7+9c7a12ayuqCSSHFI9jO0ZlCYbZ1fa8flOI2fn99z\nUKOY7x/flzMIt4GQh+YhvZxFI+NzEv/lNQf9GyE5dblZla66rgMHZKhy1H+1\nNmlf\r\n=C3Qa\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"be5f8922005be983e141f065a6a51ea1b25aa712","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.16.2","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^2.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.6.3_1587583073654_0.8781079911073837","host":"s3://npm-registry-packages"}},"3.6.4":{"name":"@hyperswarm/dht","version":"3.6.4","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.6.4","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"5dc9224fb5ca4403e12ce4dd946483b89af3b0a5","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.6.4.tgz","fileCount":20,"integrity":"sha512-wYDRnm9PuGq1SpmehIywhMoPEm2JoR8g9UodfSmx7TiCLMAx6o0fQctjOGlDj3IL1w7bmsCyMB6Syks1b055pw==","signatures":[{"sig":"MEYCIQDJCORpMCY3B1m/k2PPhL7wOAipTFUmn7zKw+vZ7QfaTAIhANJSi3UaGx0Ds8Am5YeB7yYYj32Ty3FIMJ1rXGnvQgyS","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103449,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevEpfCRA9TVsSAnZWagAA3vIP/jbgEPaaG6qNklMajBQ1\nEo34dee8ZmmTSTKipCUqHlxFymTGxYgdMU8kFYFYFS69uZJt12ENcwjYWeSj\nV3gQD290jmilD8DPnzegg0YP0IsNKkquoayXoPo5UM0KUkGJ82waTjrrg4+n\nPnNxxlhHmN7xQ674zUbRFbV/pLMNwMraSDKTT/ximGoig1nBaWH1ELXsf+AD\nk8/zlX4tFxN1TUHzOqNYxDT3Y1ccMoEdRqEFdXxvX11Hx/uLKBTs+0uVojQ5\ncMTWJOqpoxDJHp0KS/gMK3kRPlAOFRoqOG2L+8qNJB05y6QlO884Yr6Y1rbg\ns5M+tojwMKWqxk+4bKFRqS0O7DHalkLfBrYdUNBSQbhaxScWasoeZKEDTpQc\nYtynYv4uxjebKau1B4haurtbYpCKH4Hl04EzrGH3NM9TdgW+bFgY+DvFRfmB\nF23IJVaDsqQMOxqJenlETQO5/j6aX4oeo6wcH5svtGFK1Uqff8abtA0uMH/a\n6+uZ/E4PlWUcuSEZOvSzWAjlt1V0D5ARvXU10GuUGTZJlEWTP82Nf5T2PIGm\n3XMksTe8y0/H1qEO4Cahwckj97szdCD1ad1I8LVv3YO+ZmZSbfuu9756JrEr\ny5WFlPXuoPaEm34XSjmyHgVp+nvOHavU+UstJaIsoO6NnMNl0tjw+CqPc71o\n11vw\r\n=2dCz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"1ea6b3f7af36921b6f4416109c2fdc0df34858f2","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.16.3","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^2.0.0","sodium-universal":"^2.0.0","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.6.4_1589398111064_0.2947670767864832","host":"s3://npm-registry-packages"}},"3.6.5":{"name":"@hyperswarm/dht","version":"3.6.5","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@3.6.5","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"a40d3b7df6e209a10accfb9446cc7580c4f10d6d","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-3.6.5.tgz","fileCount":20,"integrity":"sha512-SJL3cVG0ahecikal+Xv4+AbUYo/PVcymD36bX7C71E3Q3iUR5eNntXRoZP0BgOklMFT/x5rzkHy6HJYYxPa7pQ==","signatures":[{"sig":"MEUCIDTsfYXo5gHUR2bWctr7gNca7g+a/gkB0tyJGAVGT6sqAiEAgL33048xRDRLJavj0KwUBYdHrK9jAxW3k3HjTLdY4SY=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":103443,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJevFrDCRA9TVsSAnZWagAAX0cQAJKBSFIMytfz/NBV7quJ\nXgqD8O0xyKfdb+WNXR6AyJ50Ase9U2RZnHyPJzsyCHCyHw83lXlXf2OtilJ9\nuC3URIqKfp34WZ1gWKS5fd1SNOpUVZOXZ1RclXUJDZLuwMNIwVRDfqTAR9SQ\nsATP4JS74ouKcgn11erzu5tQtXPrGhTaZ45Sen1Fr5BwB1PA8xhS6Mph4jvv\nQs14I4+1R0NaWZfLXCkZX6DRw7E/pZeBNU64fFae6Szp72QeKdzrssGm2thP\nOaut0wH3egZ0XuDzQUqdao/qJmo4e/B1LN2eZL7Ze0N2iaJk/8sFoy0CNHe/\nzVzv9IxthkLjHodExKwwGGPon8pLO8ROI0XKmuSP4N3dYVPRYYSkYLDFPA+x\n+CW6inTp1MBPCiUuDnzWLsZFJBPPGFC/1OEUAHz0LRmIqUW0F6nYleZ/PPeI\n3tl8X1jSzQqvc0jGAvU58HQIcFitrhRV6d2Mpd0in9rUnbpfrRA6+MZTjPLj\nlSav4LRPAqDa4y/FG0BIacfJBzmRYlFOR4avqWEeHiK5CVXpqVdIoHFcP5ka\n0jgCMzcEL84+VgK9nQLrJMLOaKEAMkqkYWobAWE+GYAlN/95jDR9pVP/4lWh\nXr/yVkjF8XMhRrfpNz2IC8KLn7eBRrtGhMGUCQ+NKD5x3eJzfCYq2rIer7Rf\n9Nuy\r\n=c5pD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"b6a9b371adbc403826f1801c6e149e78961476fc","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.4","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"12.16.3","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","uint64be":"^2.0.2","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^2.0.0","sodium-native":"^3.1.1","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_3.6.5_1589402306879_0.48008219748923686","host":"s3://npm-registry-packages"}},"4.0.0":{"name":"@hyperswarm/dht","version":"4.0.0","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@4.0.0","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"e1cf0d519e5a0f335047664ed841a22a2423df97","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-4.0.0.tgz","fileCount":20,"integrity":"sha512-BkbMg+HySIro4mqunjICnc3Q/rt1uFNYhCQOOfHLVdkHeTJnCVDR4ftnFSlJ5RYrk1UbvWkWg3KcPymbS7WoKw==","signatures":[{"sig":"MEUCIDKteXtxaLxyrLz8FspeWJKI53eoh9sqwAyzeg+unq1HAiEAsbYIg2gDhqvk1GcXMQavnLmx+lvGHFUa69LubIkYbfM=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":98212,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfBzzyCRA9TVsSAnZWagAAmwsQAKQuO5ctZ8/FawSioOEF\nGmSXphmlXVZ9GBQmpIWWHQpIzlHY4K9T2uDQkVio9NRWV849RAFfdfHurikE\nezO89Qn/BYShe8SbD60wxLgbrJJcLtNEzmGBCp6ycJQsVTUpkeofOCPoEVnb\nq2EEB8VjNzECiVbhZW8DZpUGXDXOZx6uci+vZuA/fjZ91RHBn/OKqDr7804g\nBWVRa99QxRboJtYVwKQBF7m2ktxoNAz9mZ7NX5XAMTJev7WADiN/VhwO7Xf2\nJaiO+WaQjJqW9TSmXXjbowZT8jiXXA5EbygZDlGGLmSnN3bgir/LNJu6tQBV\ndmtpj/1xWJniX08FzhtsfD1MuiHZHx4VXu6G9pMXr3WSdYxSRD1I1O773Brw\ngh7GSANtabaosM+udbR4SlnKzquY3XNxJojHXd+zF1baCRvjaxkxqk7JMWwO\nHrRNW30oDnJyg2eFncriylaQV54hnlx3CW0uht+bKY4gRcbm23KzgTb59dAS\naANfgXYt0kWU9r30y4KlrjnlJvfDn+lMafI2bSq+l3vi+WpNKEYNCrYOjxRU\nOE5729cJDvuHDUaUWuaWInKtEHMJcjOXJ5wlKKcUxgz6RFZ1EHPDlenVr1IP\nts+ZIatzzXn04ZOHHT/xKHS3BbQeGZ+DXPR3yt/kgQ6CFuxkU3Pg4oj9AXS5\nhix6\r\n=Ffua\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"90d1ccba08414a7010928c8e042124a3ed4d624d","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.5","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"14.4.0","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^2.0.0","sodium-native":"^3.1.1","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_4.0.0_1594309873868_0.1825246279866617","host":"s3://npm-registry-packages"}},"4.0.1":{"name":"@hyperswarm/dht","version":"4.0.1","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@4.0.1","maintainers":[{"name":"davidmarkclements","email":"huperekchuno@googlemail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"f04b49e672c4cfef696e674dbb462f97d9f7a89e","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-4.0.1.tgz","fileCount":20,"integrity":"sha512-wMBbz0m8rgQMERt/Ot6BGo5Y8+ovJSZmqxF0oA2xYPT8vCVBIr8g2F1BkQcLbX2iKRLXRnhic02OEq8b41M0sw==","signatures":[{"sig":"MEUCIQCZEttPXl9f42XCN1j2S3oPF8xzTeb5ZA8VjQjc4IXcZgIgchn5qhZBCxB6z6TSssnxrx86UFaJSY7Mj3oQLI44G/E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":98219,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfDGeWCRA9TVsSAnZWagAAIkEP/2IAwNfWMMFqLMHRi8Fk\ntoC2e/LTaAlBnnBBGQtT2O4NdF4dzMNcNYGWjyw7T3yXBOakp/j+VPB0/9+4\nGailKXrnutYcxgXTl0x+hPoSLB0kj419MwXPXOX0zxB/stZUDIvBIxvt6R+t\nrVUkEhXq76xOr20bgbaCwI8Xp3i49g9hTRlFJaNZ3OVW516OPhtOmHsgPD2U\njuTBwBwxLkCBtYvUJQloWj2FcibtGUb1RaxBjB1b66Njj6wOqGnCg6wDiGl/\nijJJtsTMEQibedVb2PeBAsylQ38rYl+TI1sbDcboV3TNSLqG6oQV3SnlGrqR\nZA0VyYRnGDzD731TfInDtootGFdmgn2Wmd++ZATN1qzlsJUaxYWeSA82TVHW\na0JzIhIrBRMD23r8cZuJIXp7n4ccw2asXq4n4dQ6pa332hwAq9OEjCx/L3ei\n5kcFKIijY0IYbRCMp+QUSFkTDvCR5ulIWHPvF9yKEv1TpoYyG/U9j21jBHSL\nQfgxbzWCDfqHq/OMfUoXOmbFHoaQ8jWZ7dofD1lEiSi6QkqUO0lxevHsGp/P\nN3GmtQg4dUsOmIdMDH8mMVVuU+/7lfpfGdjrt98ATLw3Wy56IGVqqBUI1bON\n3dkFxtWNPLP6Rr6zzJn6p/ckhsq9mB6F8f40Iw4/BxFfaGNA5yaIVDJmvTI9\nDwt1\r\n=4kK2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"c8bbe643dac374d9c7cf92d723b732a980c564bd","scripts":{"ci":"standard && npm test","cov":"tap --nyc-arg=--exclude messages.js -R classic --100 --coverage-report=html test/*.test.js","test":"tap --nyc-arg=--exclude=messages.js  -R classic test/*.test.js && standard --fix","protobuf":"protocol-buffers schema.proto -o messages.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.5","description":"The DHT backing the HyperSwarm stack","directories":{},"_nodeVersion":"14.4.0","dependencies":{"dht-rpc":"^4.8.0","hashlru":"^2.3.0","record-cache":"^1.1.0","end-of-stream":"^1.4.1","guard-timeout":"^2.0.0","sodium-native":"^3.1.1","@hyperswarm/hypersign":"^2.0.0","protocol-buffers-encodings":"^1.1.0"},"_hasShrinkwrap":false,"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_4.0.1_1594648469857_0.024189144770020876","host":"s3://npm-registry-packages"}},"5.0.0-beta2":{"name":"@hyperswarm/dht","version":"5.0.0-beta2","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-beta2","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"dist":{"shasum":"610bae08d90614d360b52e26e7bc5f38ac6d3d80","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-beta2.tgz","fileCount":10,"integrity":"sha512-BZ3BtwTz+Uv6FAMZ34pkWGpymG49GSqncZI8nByVvTm87jfmGH/+PTCEIGc7AkPYlVf/9hjpmyMbmnum7somng==","signatures":[{"sig":"MEUCIDQSonEh7TiJmKfWjeb8XmXeMUMqNv2pTXvtTcMRi8NPAiEA8fIP/T5qbDCRlrq1UAtExoIjZ900R3ZNFl6tB7kD92o=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":43372,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgtmwOCRA9TVsSAnZWagAAIhsP/iVyvQaczxAZ5Z9AGNB3\nQeNwQxA5Hr+PV04SLg3xED1K4ANB1DNktjTuiezlaR9JiOA611yH3J/uxGnq\n7ZuN3IMeyaK2uGz7HXP4PAzsDgIAKfPuxjd3MU4lRdyxUZwlgj4Vr1zcn4x4\nkl91feDVBFSJStmqsz+wxKOfKYKZkH7rt9ifQgCwsZ92GCau1NbZaAbhJcuX\nWlKSNzUOSCujD7DEhsdotbMrMZqUdYAM8DjVqGOn6ajaCf37c19P3OLMkcEJ\n7Y55dAh/wHEpFLqBTPrSuJjxZX2hh55X/d8mzom1uWt0HhJGbIGFomsqbVgh\neFhjjPWjUjCsEw53BmDTks2+5mtobTFlWEci+RY1iGCmwKoooegUZHlnKNKh\ng0bBgCWnQZmOgVQNBF6PnyV0pdXJ1LGo1KbXgmkL7OWJPo8eT1yR/hnAz3YF\nXX2sTqPTr7sQdB6cgOGU3YBTj2Wm8Wg0UCse3QxPHjmSL+yhzfV3Qm77toW2\nXXeXQSW2ryfTKgzFmy1V9GpciBlkjs769maRNaXa/thJGno9kJik3Pne15Ig\nCsqx1x8xoRq0rddG/1H2dZY6EcA+mEUXDyKuKpSFh/wVvYIOmOwr1NDqxyWi\nwIS9KA9+VAoWJ6fHrP/k8yKU3xAC6Gtb8WXVxsrqbZYR6tNDoDwWsJpkcia4\nrwPQ\r\n=pfof\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"ERROR: No README data found!","gitHead":"157590e9f7355cc9d9d700f64c896244aff4d2f0","scripts":{"test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"beta","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-beta2_1622567950093_0.4281206226530052","host":"s3://npm-registry-packages"}},"5.0.0-beta3":{"name":"@hyperswarm/dht","version":"5.0.0-beta3","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-beta3","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"dist":{"shasum":"211e2ba591cd5ef666410929952ee3ee30f4b2f3","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-beta3.tgz","fileCount":10,"integrity":"sha512-kwcZXNXkLF2X5H5LZTYl9PhmWlNOjllCTKjdFK3hU2Q70KvMD0TcaTIzdCt7ApyXYll3gxgMMrfcwW5hxWGTLQ==","signatures":[{"sig":"MEQCIH93g4svoQMwuJTaxoIVqZZjijrbcmYuGrDBmEXvaJshAiBFl+CUKG9Cscbo8+8hwRjX9dcCC/dRkLlwkLJgmDsgZg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":43372,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgt6+tCRA9TVsSAnZWagAAS9IP/iczbvElGPW3B1ihLZwb\nJ4f0nCmZcatOuDpRtbSaskb/+PBvll2jxThTrfkvbzi4i3ZXrnQO7I4W9D8C\n8Yf/1PEZWOPFB/MgEpN1+lLEf1IK7B6s4+e0bH/vV5iEfefKlzL0IB5aKaq+\nYqLS9nyWM74NXNrRrqxvSEI+CSBgExcdXd/QrwxgI2ELAXM0l19lQg84y9Cv\n4no7x2nJ+lTzCOoeVRyCydTDiOKlF9L69NnRhZR/2zboM4tQJGu23WUIkucI\nXghcjWITIGvSk8BJTkh3XjSvbMEJ7AoT5r+0Fn7rlNuWTf1qyCW1vxEZ6CIR\nayt96Mjr23ebGdfNMqJ8XgaS2WE68AStemzYQTK3ZvsqWoe1s4t8byOkECUk\nohh1xmsaFxZZAnGv4hqdGHHLG2hBeVl6+JODIYi8ULAmIDKcoQ8yqwPjBDzH\nj3YPK7+g9NVg8TlL9xGPUAVQp3CsuuTj6nW2LOUYuhNpwISJAfPSV60Kq4wZ\npHxGJb/IhBXyrGoVHUNeRejs30NzIDPZKZPH/sbA6AN8t9sYZbCFlvuGI2Wi\nUtkb/AJtNLI7gDKcyp4P5FOKxtS9FJmGjAhKwNN6RK5PHm2vRv+f4j6HNMse\n5lxD2yERIJMZuuzMHNILloYj/kiOP4vPaxwIluckjAUX6eSocpKnzHDyARFf\n/c0C\r\n=UK9X\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"ERROR: No README data found!","gitHead":"4924181a602c661b3d2d7af51a5143b850b2d1a6","scripts":{"test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^2.0.2"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-beta3_1622650796968_0.14708714174456672","host":"s3://npm-registry-packages"}},"5.0.0-beta4":{"name":"@hyperswarm/dht","version":"5.0.0-beta4","author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-beta4","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"dist":{"shasum":"08dce95518337a52196edf214ae5c3c715f587f8","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-beta4.tgz","fileCount":10,"integrity":"sha512-ACMJoF63eigZ9z4msLy3jaePAb/TfzYDGpJTM6LnYpdEWGi7tdekqnbRNEZquz25+UVhJCVY7jDNwUzxKBDHwg==","signatures":[{"sig":"MEQCIAcyiw/46ZQxHEDJB7O1h1E/SQfDjHGmIcrxGAV8n+MWAiAZ+ImVlBRk43bmo17bd3NeXwvl1TZxC/rycuIQG3yM1g==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":46774,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgvj5VCRA9TVsSAnZWagAAxAsP/3cn01ZLQaKTKRY7nXgj\nE6qAXmlUk2GfahV6Uv0vKBa6yfbpgpmovXAvEHuiBJlsznaL5j5fddhL6rgu\nJ+Cdd5ZSvK2h5pMEiWJq4kgyy/ULPOawicX9JZHdjIfTdGlxmYheKfYluw6D\nRNL0LRSmoaeCvbxXQfqal4nvtpoGZszTWAK6GAc8mtQdPNFGL8lyF9QJ88LO\nSAVYzWP1KNV2U2RPKwesNIB7GXcc1jNqrEVEe8qhwosbwmtYguZcDDr4AgjX\n2WEcdHzmFz+c9gkF6AAyyPg4WOfb1kKARX2XXcLR2jlVXJyorLXumAw3qA6t\ndfMVPy8pCxAeRl+UMabtKrOsL+HtpCQBmZudy3w3GpvZSFbRv2cRnDP0odVS\nnQClrEI5S4nyOVD2t9J1gUY8xiWJA8POdkvmxKGYPgecAb+ZKRuhqefnMPH9\n+aNH+RBmE4iNz45gpVDjxAYSDZQ3H6FK3bQlT8hwTgTASG3CqB3hXFd/M/Qm\n/QT06kAXnLfRavaNi8ql/yUP+MxPHDBL3hICWZm9ITsspWkVnrKDo5R7asMr\nxk6vb54aijZe7EBlHe2GT5Rp+0TAR9VCaT5wDulRTPxlhfGGzHDCj7SQf050\n0BO2onIYLySTQ/jtSSUBNxGFhdphZZPy98Eno3w8dtex5tlHNWokP+UszFfh\nPOYC\r\n=Xs4h\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"ERROR: No README data found!","gitHead":"c59fc22879306a932bb4c9a0dce46efd5367839b","scripts":{"test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-beta4_1623080533587_0.6764400075539667","host":"s3://npm-registry-packages"}},"5.0.0-beta5":{"name":"@hyperswarm/dht","version":"5.0.0-beta5","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-beta5","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"f790f673f11b6c78db87ecbdd71577729f3492c1","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-beta5.tgz","fileCount":13,"integrity":"sha512-tZGSBc28LvF369zrbRw8d4xoQe+TiKDnzZowf0nVYTLlKmN8bTuIArsxTqFQNiCS55vAeugwJUEVIQEyYHRIHw==","signatures":[{"sig":"MEUCIECWiwG4iofPdNb7MqkeWUd02KTf0xW2rA6AlVAnf+mFAiEAuNbmEXbB58p4WYAYLYuRqdIT1Qi3GaZTd9EU5iqmX7E=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":56879,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgw3hQCRA9TVsSAnZWagAAr0AP/2mzeAxhfOKbZJpiT5vp\nQEgRWFcK1m3+hXzqKit6Z789u5LZr4Bt45/kHQg8rCPnmb9eKtmvUVf2/47P\nf48MpCFmqkVFkfxELbd+3C8pMr/BPq6NgKiTdzkEENfvS8mzP8N6Nkc4zbCt\nZ9tkz2KJCSp0bf7sL3DXpRb/K0IQNc61uALO6+zKkADw05UkyQygXxvabHWI\nI1SffVMDhEc2PeEzzVTcZdRFZpTX65Svb8qqmMiuBHCJJ88+r9TvFnr/jS1r\naGldNOXD35AvFFZjGnT5by4EQXGKaKEYtr4x9axwa3ZBWFS6S1fxp44JwjKt\ndCME2Ud14GRGQ2oq8yrcEBwAFtKvNWyUT3dwj2Homc1fjyovAVWNQ1XdatFs\nzvek/9dy6yaAt3m1HBjUM0uKw0XxWfZXj9RctsH/5YCE9vs6vMi6W5y7tdfZ\nsIXjuEMWS6ly0HcxoometLZgS/E/oqBqMHEthQJ3bQspP8bd+anHOfkjAAYZ\nth3n5vOr7HAafKXcsFsx2zKnvtzFC3zwIMk8fg5KIKdXcQxYvDeVQ2tNVqfV\nqwgC2WSbZJVLUYgpnWX/1OUSTAj+SrWej7H76cCjjqyGNnlojYgrr+9lo2Mf\n8uhRd3z9Mx+ig0MoPsWlPh/9Le9hoUmlDagSAaCaUIXjGRUMDXMTvhbLBapD\ndlWx\r\n=cZcW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"ERROR: No README data found!","gitHead":"1c706e5b8fcf2d3c2e5f350f1dbb970e21acb84d","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-beta5_1623423056512_0.5019961158654451","host":"s3://npm-registry-packages"}},"5.0.0-beta6":{"name":"@hyperswarm/dht","version":"5.0.0-beta6","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-beta6","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"a08cca07de515c417dd89ab20a16fa6ecd61b807","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-beta6.tgz","fileCount":14,"integrity":"sha512-q7/rXSB5IrJWv/M1QE8Rfp21m7LXjl2VlDfGhrkzozUl/gMWG98wwU0PMJ5eWkRVTR0D3nBZtpyImMrShrYgIg==","signatures":[{"sig":"MEUCIQDpEZfe9RJJvctj2KLOfT5Heu15bwnEZDdsxfZhhITLUgIgAS4sRTVXcPm3HW6pdJfdgDnS3kjWJQP80lceHfDXX5Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":63908,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgx4TZCRA9TVsSAnZWagAAU6UQAJ48KyypUiHmxxpY0Tz/\nfg3fGABgO5G3A9mAFwdF0bq68bwoheieDgfatH4cGiBCiMwGOra5IlKT+yz3\neGVppnq7bDn0da14aLAnqRdB7XrZ/6fMPNCQkab7ayHXPbLjv+e5ZviWlEJP\n9egD7kROqNQ2DCQxwYDOd2L4L+IMEvCDNHrAMBrvkT/0Gnpk0mxzBR8f43Ly\ntzWc0e7BqPsDfg+PWLzfxJSUs25bJ31ecjom5tMeYs/jrJ47kT+e6dAD6anb\nVpISYoGMLVepJ+6IIYYnUrpE2nNehgnXndhrt0k+/JhikMHFaCuVw3noQr1X\n6ELBdgHJHVsi0vFCvHSZzbAIImO1Zx2jBfqHm053OxnExydLrFf1ZTd7g15w\nWaV+McrtxFNi/lM7IlTzW0xwPqd4h0EoZ6Wy8YhFfoZ20vAic7oBi07/fE8A\nMIRlE+LTyGULPg2lr2KLecsFVvo541ADoeKdSZKikNPJ3+10+NfXhVfsQ/iO\n3YrNb9h1xBsZcd+qC44jt20QoaXc5oJKJ9QfNRnva7rgB0RnpPHYsrxK2i4q\neYti29XO9pAKxr5KvoOD4YwhW5HalKIr+cTx9zIyPoGTqVSd+pGQTP2pkQXW\nFOuu7GgWwJtlaVNyzIiiX1hdCt82vhQMhdGMgo4nRhOvjoVdF+UHvFGpHZiR\ndqqp\r\n=tAsH\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","gitHead":"85d8991360093ddea56de574825718efd731a4f5","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-beta6_1623688408908_0.749988287394399","host":"s3://npm-registry-packages"}},"5.0.0-rc.0":{"name":"@hyperswarm/dht","version":"5.0.0-rc.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.0","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"eab579d3e362f85461d391dfcb4981028437db86","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.0.tgz","fileCount":14,"integrity":"sha512-4mZAomDRtqzFSd6QjyoyKzU30iTvRAuJl2Kf+RXyY8vumLZ2cO6fk9R8LdnGqpH6/VXQ1UES1yNMO7NrXNzbyA==","signatures":[{"sig":"MEYCIQDSkYm6/05MF7cSruc6dhIH/NsFO2w78SGX/VIm6GIs3gIhAJLcWFYtJZ/K4IoiTmeKvvWSP34RSl4Xe3l9cC1sQOGl","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":63936,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgyyPjCRA9TVsSAnZWagAAFJUP/1xgfuVuXNqrathqymaF\nKAPC+ls5BZdvidhnlvo6pS3zKgBKsgqer5+N0MuUMR0sPlfuQxdy89aNEQXX\ntmcNDTb0a5fSHJlqGBfs67Cbi5xNOo7NPuiIqW9WwxUKRhwFkMenPTWzb9Gj\nGrIiAOrEYZdiHVe1IiWxh7S6QS2/2evGGatXrOK4RVMejcZ/bXFHqFq8jgdG\nxZoT/0MBaIoK18PmTQnQrZwBQXCO8wq54WlSDpLVJN2VGcafZsNuttsco+3b\nuBu/1AxL0SPbxqAHC2/uoYVFp7Cuqlqtej3KBQiho8iRIlamoXIND5HLx0bT\nPHAdtmDf9j6TrvQXLpDtcSim4lYih18dkf726z6OZKTp7Ec81KOWG6eSPpLS\n689hoEtoiMvzqGIrV8mPiJwwHHlux1LurL/ymuMDZhn9nvp9lA4pn7uScN7B\ndU9N2Ad4+ec4f2hc+PEM7nYvBc3F3Bm3Ew/eMqC5JAE7huTzqkuGg/gehWdZ\nhvhvi/vSr6GxmtPR1UXapKmE5w+yfeW9Yjk4A4Ct4X04lmKTXQh6R/faqXu8\nkAQ7KJLH+jEMh078dPPzt1Q8AwI7re6lyOm+zuUAoim7gBg6yJiuWsIkEgRj\nbeubVk6GWQg/DsPlLeuTUrnRQkJzed67xeMwSSMuDEUO3KpIqWVv1FOD3epk\nPMHI\r\n=TCCy\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\n  bootstrap: ['host:port']\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([salt])`\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#### `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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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#### `await node.destroy()`\n\nFully destroy this DHT node.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"60e76e3958264107c0bdc3dd62e67f6c5f0d5f2c","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.0_1623925730499_0.9684746224546037","host":"s3://npm-registry-packages"}},"5.0.0-rc.1":{"name":"@hyperswarm/dht","version":"5.0.0-rc.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.1","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"1a4577d5086923ea21ef8dbf584fb0490510f562","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.1.tgz","fileCount":14,"integrity":"sha512-qnAH0HG9P3cdHw1walWyDldidoDNtO7YD/2CwZSViZYCe2vtEMzr7vdqm0evGVJDJAZ8oO613lLAg0juShjcPw==","signatures":[{"sig":"MEUCIQDM0L/G/0n6LYZkEAuPSjbcvDGuxDX2/jxaBRbDTdQYewIgeNoSzuQARwPnuiFCQd8SezfoL7pak5fHdZogp7++tk8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":67852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgzJE/CRA9TVsSAnZWagAA6wMP/08wkuHpI0LxReTP294n\nY21YxhvJzbg01iC6bBu7Tus9jP+MeGBlgyhb81lhXTwruzLT9qXetDRBFL34\nsf/pKN1wHY+lu1ymufq73izlSzReH3Msn91slfSpdFEsb8rFhd7E/Qmnwdc7\na3Duieq+gXTTaD7kYkNWA3jyF2upmEHM/Au0scPaDcZK+DHgZ2cBMT1pG/Ch\nzKbdt0d+Vo8bjFi4jwxlNM+K4RQ4H5y0HW2csYB51/FJlqemnVlWwawv44P6\naOgpkwj6TgKTw/rokRevR69O42ss+9/KkxvGSMoz3nyr9lqFY/9+HkS57OrH\noSjst+UE3cxmFgKnWtRwSpAhNAgKNHJxsNdbaqtmY3JH3e4pKvn4ou2Sease\nrCI1NNfo6JitjzVC4O2YqhK8Pn80+1r7pLGCjxglbqlPL4saPPtQhgXtRNnF\nvTE8Q9OqfGfTO37NE63kSHWHtrU6P4PabRRZoaGsYCR9dgFOdT+T9gcScWOX\nvv/R2ObVd3YEbgzQckysq9L9/oFj8MTDE35LJN/PxOfn421ecTXVWmQEA21S\ngSt+wqbsb6jAuW+nFHbUszTN8CsdQBDzjL6vNnHldB/5cMZunKCvvzHuUqHQ\nPyIUhDpvkjSzEwM2PU9uNitDgDbPGaiC+qG2qLVy+OXieM2S+9XrDRXl0aQM\nrOFu\r\n=bkCz\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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()`\n\nFully destroy this DHT 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.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  type, // NAT type (inferred by staticstics),\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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"ebca7b3500de7efa4370e615fa6946c76836dcf4","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.1_1624019262994_0.8106994886493466","host":"s3://npm-registry-packages"}},"5.0.0-rc.2":{"name":"@hyperswarm/dht","version":"5.0.0-rc.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.2","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"19a7a60e3844965f90a4d9009f0a648fb980d2b8","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.2.tgz","fileCount":14,"integrity":"sha512-QXL6gxLixhM6mYKVbTSb8cYGWkiE91movZQVp4QolVfyQAogNaqzpl2GiZkO1EkE057fIr1aPoUPxHNArqNA3g==","signatures":[{"sig":"MEQCIEy7fg1IJzr2I5ibPHnxteJAPd94qcDMZPVxEW9Ld8ahAiBTTUPvDdWApwJTL4PyzxSo5bwIV0mo4c7YdOGhcTQmYw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":67975,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg0bHYCRA9TVsSAnZWagAAa/kQAIchHCETHomhRF3sqnBa\nuzwAPcyVjnny6hlHyDEPPwIHV6QMVQ890idEHOX32T/7NP0mxwLRmwlo9PwU\nWupiSz15W85ZpLZU1GjUOCJTPGfutqGTUr1CMIrwRx7FZRuVmgR1FdAw7m2U\nGDaypFm8FKVKhsthTptGv7X9njEFfQwjg/iNK3/+ms/2LP+EvJiQeqvlnwXv\nAWp9Y7bujdAPxOdYTnVnJETkFX17w3RWZsb4XmEFVhfaohvckbjqg0FqdV1h\nTLMVeDWCs6OjR4WuczIOR/M6MIdvhpf6y2r2vHir5XeH13BO0WmzOSLIN59j\nroU8zo5Qe+70GrpKE0jv/T1Oya5elwvJjnKzb42oq5/BxfcCLAbi6luduKP2\nHyDqd//h2vzG6885EaP9sF2IZbklEU2CfTZNPmC97G05ngN4va2f74LHnqfU\nACu4sT42gW543O5bRl1G24biDYBkXt6ATApe2JgADmK3bliHOUEtlSc4xK5l\n0ABiolN6PBkPjdVrGFl8DMnNXZkOeoPgmHofC8KTKp5gMKCD6J/1iNcD7fAt\nBirhdZouwWrlp7V9xW1Pl00vzEB28sGFglbVGam+6yu0iYNxDaNGGhHFWkQG\nLUS44jJ2bJynQZCryvIzLjjy6Oqz5vxeOYtodzEZPV2XjlOmbN1Z8CyIWbsO\n64Ik\r\n=5ss8\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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()`\n\nFully destroy this DHT 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.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  type, // NAT type (inferred by staticstics),\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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"db96ba3899fad3d0b29b4f9a4f612e89e51b50fa","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.2_1624355286540_0.4895397285296059","host":"s3://npm-registry-packages"}},"5.0.0-rc.3":{"name":"@hyperswarm/dht","version":"5.0.0-rc.3","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.3","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"e95aff92b943549860cac35a23f71f141772bb3a","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.3.tgz","fileCount":16,"integrity":"sha512-n71MD7ug43hS8HSWfgwaONee26r4+U9k06Taqp/VMpG6ok4dfudFAt8e6yglp037kIFI2zWVf2gXYLuZCi7XeA==","signatures":[{"sig":"MEUCIQDocpN34/66RdeHftuatxLLsNsd5D6/XK0n61vvG403hwIgTQuHfRdbUUp1QELJJzgINk35rKpTLly9mprQcjDaSdo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":70687,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg5V07CRA9TVsSAnZWagAAqw0P/jpij/w//7+1H9W7TM1t\nBcmXMQ2wDI0MzOLbCcTZp+ZUoFdoP41kahO8iNYR8C97S0jjxs1pdEqY/r6Z\npTH15Ft5Pap5gjkCek0TkAqXHzMWapyz77g+OeottsY5mT5gbQMCNdQTRqVS\n1AEBEsDmSofhFN9/JYWgoI7pq9i7hlcG3WeC+2bYwiVjXVmm1v3BehMSjYr2\nMzl0PRHOUn68+OXsCJACSt7HD6IhYw5a5VHE+MUNRpdDuQ8fEB7dtH27nlsC\nqZq9+YqTyPCkQoSfQzwZNRsR4LmuiGsCQ0AIPx2BaGSbDh7YqnPIPZHr13Fq\n3ez+qkHL1QhjQ6grtas8EEPzktykKO/u4//b4DcuIzS95+R+ponjdfeElLcN\nzEGUAYAY22ULZFd47+wd3xnB0hrtlqYCAMEARSClCs7PdyuWjrNBLFH33exq\nk8jsD75ledEMcOfHMTtvVW1dXvOcnDROrEeyBOkDEzc2mQsRrmSr4qnBIjyk\nJZL/IQ89zMkNRH154Aep4DO22m0IK8QTGp4/1I+uKVNm8PmrA1vcS0IqYnJz\nAkkGyCBflFXaNxhy2v3rhdDN9IICakhAhJjp54Mdy5xaEKaRP+11sRNH8yRy\nV/hY/zL/Tqs4iL2lqALPNfrmtZb9GjgNeNTAMJ0sNXq8W1+FXkUiZ40/RG4C\nIqLl\r\n=mkwq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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()`\n\nFully destroy this DHT 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.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  type, // NAT type (inferred by staticstics),\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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"8044e52e13077a4c552e82a231f00303b22b2cc1","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.3_1625644347270_0.5895990195760723","host":"s3://npm-registry-packages"}},"5.0.0-rc.4":{"name":"@hyperswarm/dht","version":"5.0.0-rc.4","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.4","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"84a347d3afca3b59db83b2ca0262edf68be5696e","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.4.tgz","fileCount":15,"integrity":"sha512-ixZUr66dxetK/HBw+B914qJJnIjWIwUJACDKyT8Os8QzKsbRGWDol92qt5ajto7eZKQ0AYmpsfmvIseRB4qHAw==","signatures":[{"sig":"MEUCIQDExLRj/cnUG2Dicmb+CYTm+F3aCTWnIrZnlGqw5ATNbwIgD0BZmAEAYfbrV3ilEsP+TprpJmXgbwNhXphkpbQ0uyo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":68521,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9ZQeCRA9TVsSAnZWagAAyGwP/R6O3esFQfSb07TPY1uV\nIubu+t4bPsynGLaIA4NOxel1utnUElWk2jWAihRYW+4YOSHdXfDq5espOavk\nMZm4H2n3y+sSU7uympMuPPF2OP78ytd9yYlUxb2IbWEF+nMQ+6H4sfENOQ6Z\nGSgFfJd6UioL0kzpaiUscONyqn1AqWFuUwXSjV3lXcmNiyr3HkDwdGAMwVup\nrCj5NThjwQwiXbJNYIBiSLvfPJFqejl96PVuip7HO/V6+5TzEPMHITKtJ1iJ\nMEYYyTUDpAmCZQ/l7uhwz+iToyjypDMZv9CmEcjIRGTYO25GhzUfFZl2gcCY\nQuhAFPpxsrXN36IidIeEC7gn1Urp9E1ttXAT9yBM+u7BvtZFlFOyAEWhf4av\nubQIyDfdc6OlqxTmAcA7WYp0IObHOAYZbfJTgcPg194eZWRPisYB+X0/sgxL\n2rSi4slMSmPvc0oSaklcTmV50O3efaHAY6/qRpfR+Ijp9kb5MEJvI/OsLtD/\ntRuXr2OTcV9VGWlp9hcnON9NGCIusmLritBmg/TxvqdnUoECfKM0I9TqLZyI\nobHaDm9Q0JcY966/alfbdrs+3TjA5KndTaxbeWdBrkASE9VpdYA9qS2VobsV\nxk2uMU8Gv2Lupe3Tu36L8503bvUU2NAIz1SQL2wFkfTwuepziK7ElCwi4Gpk\nBjZd\r\n=qnPw\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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()`\n\nFully destroy this DHT 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.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  type, // NAT type (inferred by staticstics),\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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"b010ff133f55854fe0db42ec7d0e1b5c8bb3d149","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.4_1626706974449_0.19026931277337122","host":"s3://npm-registry-packages"}},"5.0.0-rc.5":{"name":"@hyperswarm/dht","version":"5.0.0-rc.5","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.5","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"be8d79b2246b82fbcb906680390336eb4448a27b","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.5.tgz","fileCount":15,"integrity":"sha512-/vVc/sKf9oZSE58NKpzLcaeV6GRDuP+ZLECtgjD0sXbW2obe8UsyE3QnWbOaU2WvTtDT8Rsoa73JDJL6ZA0HFA==","signatures":[{"sig":"MEYCIQC7PogGSQa5RTjJY6L1/hThMTKQsOWAKhPmFV91cSFrtwIhAN3iDQuDvH/k1J/LE5QbFvA7aypK5/unkhWcDZtzrNlS","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":68526,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJg9eImCRA9TVsSAnZWagAArCkP/joyJDWcJGv9Ps0sE2Nd\nc7/AVGdgiOfyS+2RihIlWB2Y8ExOTXh0z7d+ZOMmyChLak5fWcAgLIeibzNu\numXMqZi2e4IxciuVknoe40CoN+HkqO2rylo4Ep1WzQrRNETliGoeteiGQopn\n6ri5YFzx0puZ+pON/L/njsWuYI4u0cd9sUPZfiGC4MHcV/1yMREx07f00AAV\nbzVsmaV94oDDHsVV5dHtwErIK+viYCbA2bk1gwvi99rW6CXFv5Szeyfop6J9\n6/F13w4hPTSojbz4p/7mnsIruKG7jPvjuW/OuFRCH4P/kxuvIGs6SxDDAHiw\nVXJH7l723vjnqyYNmLvizzTjKmJiHTBUoWoDxU96Fex137EdAuDy/VmQeerz\nI+l5lq2a8jm1wdcHInZbQvm0FSVrM6DAV1H3+cU5fMDySzqLjn1PDjj+IyGI\nQuFTNdAbMKbcXDdeUmlkQz2lLmbo7AA0vomDu5PCQl00d8vvv+rqaJtYoRg2\n898vcQwvP5sEk8wWUvlEdgiZWRN9Xmgvw0VvEHvbqN9WEeqgh9kWGgM/v621\nAXaWl/b6h7LOdiuSBDxw7Z0fHSpd0upR6VrXw5ZO2n8ILdDGv+XRciyoz2eq\naj83QhvgzadnJl/dbtcLJkdV4AhTP29fpydyokbVvosOszlXkxSY8R+j2PGz\n2FRH\r\n=2+X1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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()`\n\nFully destroy this DHT 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.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  type, // NAT type (inferred by staticstics),\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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"0424e7a0f5f90f91845ba531062957f62951d19f","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.5_1626726950029_0.6755272505553507","host":"s3://npm-registry-packages"}},"5.0.0-rc.6":{"name":"@hyperswarm/dht","version":"5.0.0-rc.6","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.6","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"9558d22266471ea5d5c0eaf824d78361100056a6","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.6.tgz","fileCount":15,"integrity":"sha512-m52W93vT6gFCjQeaRcXhojpbpS4df0gYFJkUIBY2tsr63YA2/tZEKrz4FSf3X0cVsomygtAerCAZg3NE2ctNxw==","signatures":[{"sig":"MEUCIQCOPFeKEV41DHpQEjtl5jXzZd/5nB9L0i13aZjjYpYAnwIgeZWb0PvVBm1pU+1XWfj2iDsXBGpjXIWizesx8iM8UY8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":68586,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhLgjuCRA9TVsSAnZWagAA4+4P/jcw5vitS89KT/QBozxM\nysHyvEJMxvbyUbHoY5E+4Y/J9C8Oho/6EwJezW5Mn6PQpq2Ebg7iWA1Q8GS5\nIX1C3yqdU6y5pQnbrjLNDksSkQNDpyBUatTWfRR/sAC5TSrhAzepf4zQ/j4n\n/BUeqOzQ/P1fE0KLMUGoWyRhWtw5rsMOAkAnYqCaNuay4lHTnCKdl6ZcpfQy\n5kYDAtORmkqIljXt/2NCu2WDLx74JXfCN1Q+Mm+JPtMua5ll9LVoqo+ymmyy\nZK/HrbFseBiR9qUCCUzNoMtP1Nlmgz3z4Lov4LBH7Yp6EhUQVFwdUIxPFGAv\nNwVfxUybJKYW1uPhHmvhUTcL+n6lcEfem5niUkJyNoji9wOTPugP0HRKhyHo\nxnpXUmZ1kHCUg5Xx6hfLpXj1LHZmOhqDQnbl8KBB+EeXfBV5/QKrgpUfECYD\nOkFNH3uGJgw45ctjgxumVMfSy8OV+T95/XyORdYVMaXTMhLU8EYkJc2C+BeV\nNfXxltmXZ+1iIjupj5dsF2ddmP8WxkxB3AuxOpjDID6aCDNJHr2huOD2CQgf\nfejUWWXpqFfslIT7krAEQxRoocY/mVxegiG5r4WyTC70fLOJY0dXY/905/kD\nM2k4OW9kBO30y+3vM+wXNGCe27+UZGI+e/s8zIYEAw1c62grtyBGUXCS5372\nKaWg\r\n=uPdh\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\n## Usage\n\nTo try it out, first instantiate a DHT instance\n\n``` js\nconst DHT = require('@hyperswarm/dht')\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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()`\n\nFully destroy this DHT 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.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  type, // NAT type (inferred by staticstics),\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  // The DHT id of the responding peer (hash of their address)\n  id: <node-id-of-the-dht-peer>,\n  // Who sent the response?\n  from: { 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, [nodes], [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 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.\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, closestNodes } = 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 { seq, closestNodes } = 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 { seq, value, from, closestNodes } = 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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"e1ee565ee40fa0c116dee3bea816f07871004b35","scripts":{"lint":"standard","test":"standard && tape test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.13","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.1.0","dependencies":{"xache":"^1.0.0","dht-rpc":"next","utp-native":"^2.4.0","record-cache":"^1.1.1","noise-protocol":"^3.0.1","compact-encoding":"^2.1.0","sodium-universal":"^3.0.4","noise-secret-stream":"^3.0.1"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"tape":"^5.2.2","standard":"^16.0.3"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.6_1630406894301_0.4353236032309362","host":"s3://npm-registry-packages"}},"5.0.0-rc.7":{"name":"@hyperswarm/dht","version":"5.0.0-rc.7","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.7","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"8723567a07dd310bab2ef639854dc90595aedb6c","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.7.tgz","fileCount":28,"integrity":"sha512-n3Q5ftHlJ3j15o2w9eAihBQl/koa6Drvm/EDSgmbJxlmDF5D2K/zIOPyATnP0g/VCN85DolO3Jt+/NoyHhNdyw==","signatures":[{"sig":"MEUCIQDerTZAWXPdEWJ+usG7r7VGd/zbvDV/ZeYx/Vvw1u86iAIgTO0e4+L9aS+JG82w4/DIOn64InoHZuPAqreCRsqlXr8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":121789},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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.boostrapper(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"d55ef84b910ab3d4c2ec95d3b9f53b1e974913e6","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.7_1634238497585_0.3480902980932825","host":"s3://npm-registry-packages"}},"5.0.0-rc.8":{"name":"@hyperswarm/dht","version":"5.0.0-rc.8","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.8","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"82c77787ec11b361bf30d318947733609a309505","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.8.tgz","fileCount":29,"integrity":"sha512-DrwLxx/C5iyOZ1rMlfUTWc52ql7sc+fsBxJYcDkOA7WJ53OjCAUqy689LwMZ0ryNPH06Z0sMydqNe0iSMp/IFA==","signatures":[{"sig":"MEUCIDA79PetjgZMf3xGHZH0fu4Df+uBtl4OZ/7uJQJ1ZBmeAiEAzY+h44nwW3gY4A3fRZUG1luDp52ApgWAIOFpPW4VRe8=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":122070},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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.boostrapper(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"cca0598d75c3070fc0ecaea0295adb0373d2ef5c","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.8_1634240318700_0.21303604847159918","host":"s3://npm-registry-packages"}},"5.0.0-rc.9":{"name":"@hyperswarm/dht","version":"5.0.0-rc.9","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.9","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"2d49aa14844c9b1b6fc892a6609015528b4f6c8a","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.9.tgz","fileCount":29,"integrity":"sha512-fnORMVhZBAgj1RZ4778IlaJAP9HZyCI3ZLU72GmSt/PPuPpHhMgQW0C/ydXcaVgu2y/zeEI0dt7xmHwoTZo5IQ==","signatures":[{"sig":"MEQCIAIplRzrE9FgfKK5p8siwpjquvgkbHDi6TKTJaIOCoByAiB2IUHxlc3y5J+o94ooaj9nxFrBSItx2mnZdJLK1sLTXQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":122798},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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.boostrapper(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"55fdf0a300b4c4b4f0769f33603faad708ceacdb","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.9_1634244198771_0.6647863929401123","host":"s3://npm-registry-packages"}},"5.0.0-rc.10":{"name":"@hyperswarm/dht","version":"5.0.0-rc.10","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.10","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"783e78d524b5c08724c53bcc7b5104fad25492e6","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.10.tgz","fileCount":29,"integrity":"sha512-qYJ+1bltOYIukLDFKEidzJznKpqEPU1TOIE8PnNS6X5W3BOohYBaiOytxIgehDZb5ieF29qour4jql8opU9T9w==","signatures":[{"sig":"MEYCIQCQDYLAwy4rtOKWb7GCOUPR4/7Na0erFx6oWoW7W4ldmAIhAKR769VuwQVif/iGlZY1O2cpeajaxs2n0A+jPtfq8ScM","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":122910},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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.boostrapper(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"a5b3a35593f092807af50a0cf60e3e1460df9f02","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.10_1634287951017_0.38217816646971214","host":"s3://npm-registry-packages"}},"5.0.0-rc.11":{"name":"@hyperswarm/dht","version":"5.0.0-rc.11","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.11","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"b439df713ef9dfe8cbee5c9595bfae0dcbf04ff8","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.11.tgz","fileCount":29,"integrity":"sha512-IEjLAzxtDEzMFFYihH5VUzsTjvh5vUgVz2OMtw2Bl5KD3R0AhPflbEHb5Kl4sNTEkqM2UY8YrttOl7a8LcFRgw==","signatures":[{"sig":"MEYCIQDN/bs/wLWzHbF9DDGGxzQI35OzaavagKCSmQsAUkPIvgIhALvHY/1xPGdf1wQNLpN3py+e3Yw3fOvAZoCXf3P8px4Q","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":122912},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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.boostrapper(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"5ac33f1ebc8c076903c7ab45c9f80ecf2c075347","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.11_1634298426644_0.9781203856515512","host":"s3://npm-registry-packages"}},"5.0.0-rc.12":{"name":"@hyperswarm/dht","version":"5.0.0-rc.12","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.12","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"59a047899a7faf74effb3dac55092091a2075e88","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.12.tgz","fileCount":29,"integrity":"sha512-bNVj/Uwf6YeFzWBYzKuganDbD00/bJ9br23dTSN/TIIlb0xemPTiFFR7U2lzVdRiwQZgMBz2tJz6zJ0fR041Jw==","signatures":[{"sig":"MEYCIQDeI0bPTSrvUrLg6kqsIRzEStqTn7vL9wLdKCRIdUsvpAIhAJ/UzlGng/84bWEhS1pZC1yR3K5qa6ae/KrI1qUI9ut2","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":123426},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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.boostrapper(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"b93379cdf3f82eebd17c25f3ef3cf6773efb139e","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.12_1634387679049_0.3333191030179794","host":"s3://npm-registry-packages"}},"5.0.0-rc.13":{"name":"@hyperswarm/dht","version":"5.0.0-rc.13","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0-rc.13","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"ae0311a01787a204200237a60506e98fadfe5370","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0-rc.13.tgz","fileCount":29,"integrity":"sha512-uIq27mKkZfjCe32hEKpxDDbpPD6iHK1F9ymtt8Kxo/jCgy1alKn4ualyfcsckQgr2GO0XyDzalS899Exftc5nA==","signatures":[{"sig":"MEUCIFlCuOyYt59fRkCIZi71UECp7M0poX+g+v0Z0wKz8bsGAiEA7gTFvGkwAPJ477SZzyTfu1Ke0wlvny9Ds+rBgg0fCcs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":123554},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5 Release Candidate\n\nNote that this is the README for the v5 release candidate.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"a5221b850ee5157150ab6557a12eadb75bc38f80","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0-rc.13_1634673189318_0.4534672444172687","host":"s3://npm-registry-packages"}},"5.0.0":{"name":"@hyperswarm/dht","version":"5.0.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.0","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"a4fcc211a88828856dc50068f0d1a8198f4686d4","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.0.tgz","fileCount":29,"integrity":"sha512-a3Om7fpgaVUkTLyDbbS+9DcTXbtGMNaq5GfSVKj8B5jlPGq5DCIuymiaxB+fVntjEA22DaPw3beVVWtUCG4oUA==","signatures":[{"sig":"MEUCIG05IgBAgbhR0+C8YbV4D5MGdevKubB2a8EqET4/Twf0AiEAoXuMqY64sxAq/ZIPv1xFwS2ZeAy/zzm9OYR0MYJbzS4=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":123610},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"41d1b9b49a487cd7cdabce22db6bc637d783ddfc","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"next","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.0_1634808245961_0.07024782666951124","host":"s3://npm-registry-packages"}},"5.0.1":{"name":"@hyperswarm/dht","version":"5.0.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.1","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"3f854be4d176299b648e474dff3c888537a82eda","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.1.tgz","fileCount":29,"integrity":"sha512-wb8NOhbrCViTgM+8IqW02xCnibf6D7UoPJuhyaxG6iLJrxdaYetfR5exNR8UlQnk9D+otujRJFxGUgIXZei0XA==","signatures":[{"sig":"MEQCIE/bE2Nj/Op1nhFRjEZoLqEhmojq7kpQl4o6rMbm62XvAiAZnJfVHzJKu70dWwWKyWFgJtuz5aPrtvFWqG9CpvrW2Q==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":123612},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"15f782269b19b0c1a6606f92f6015938e444e611","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.0","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.1_1634816286879_0.43962525577814815","host":"s3://npm-registry-packages"}},"5.0.2":{"name":"@hyperswarm/dht","version":"5.0.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.2","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"0a458206adaf2cd2d2582bba970bb024b2d485d0","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.2.tgz","fileCount":30,"integrity":"sha512-7cqef1u9s4PE4/Wj6BrYxqqdeDOpFUN/IIzFG4uvfNWjjosMHhvOgt8JWb1iJGWGZRvT3L3lvdjzkmaP8YJzog==","signatures":[{"sig":"MEUCIQDG2nI51A7RRnwQ6gv9y8ddXhkAPSLTTW3Y2W1a8vgKyAIgH78PKEMjAihmAXrgz0ZRaFBfXekE0RBMeu+N7PyhQpc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":124157},"main":"index.js","gitHead":"37d20e5cad36c63eee8275bab23e444527cca1f6","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.0","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.2_1635249727386_0.7537707213418492","host":"s3://npm-registry-packages"}},"5.0.3":{"name":"@hyperswarm/dht","version":"5.0.3","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.3","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"3a4b0132565d0439759871cd88538fe6f7bd5211","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.3.tgz","fileCount":30,"integrity":"sha512-qtkv+ZDj70cnDL9w1uhlmaIOmsvHVWUDvKTBYf2hned6dleHr/JzH4P4X9wkMXdZ7CpsboDNYyCAC1IaHoSF+g==","signatures":[{"sig":"MEQCICZvIPvMekhtyDxgUIZ1ynVPDw8hKhMz8o4v3HgrDnynAiBn5GMeuI5+ci2sxqhST50xnp4jLDYoBpmlUhkKaCYecQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":124167},"main":"index.js","gitHead":"55dc55118f66df31e4cc1d8fa8c97c52c8de2b9e","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.0","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.3_1635422746430_0.4353930448776375","host":"s3://npm-registry-packages"}},"5.0.4":{"name":"@hyperswarm/dht","version":"5.0.4","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.4","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"271a1ad2c8e2ebe6573fe22bfd87e2245f894de6","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.4.tgz","fileCount":30,"integrity":"sha512-l4/Xh0MilvI38GPdbso3rqAUgh/3eXy2zR1r7o8WWvwINE+8lrv1sXJVsTs0atWSLr44ug0txm6XQMTaYTsadQ==","signatures":[{"sig":"MEUCIE6uKcN5FAQe+gllBMHijrnBd7xsbe4xvndOD2LxZ0PkAiEA5QgxDZVzqxkArkcjgmBQE0gy6rD19r7QRh5WGo5iBYg=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":124166},"main":"index.js","gitHead":"4952cb9007d362bf8382c973ddbe0257f5d03bbf","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.0","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.4_1635423057686_0.3904069617435817","host":"s3://npm-registry-packages"}},"5.0.5":{"name":"@hyperswarm/dht","version":"5.0.5","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.5","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"bd35249e9c85f3eab33c108eb93a85e8dc3d772f","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.5.tgz","fileCount":30,"integrity":"sha512-l51A7PcZIkmVQqmsJ7dmb1GSl52CW4a0ozouRceo2WqPQcQUZxseK/JIYvUmdqzFH6Z+U7kTd0ucaH5kRMsTZg==","signatures":[{"sig":"MEQCIBzeZWNoZ13QYMkxHQ4PgwEppWh6RkM/lpSnM6qt8Eu0AiBXupJVSTCsRfgBOga70xFNTzvV9sb35pwj2gYSDbJ9vg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":124199},"main":"index.js","gitHead":"98ef319734006e71c39dec7f78ec4fabf51c608c","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.0","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.5_1635490924683_0.11224748715287935","host":"s3://npm-registry-packages"}},"5.0.6":{"name":"@hyperswarm/dht","version":"5.0.6","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.6","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"735c2648ce27b97782a2ac49ea73774fd1973590","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.6.tgz","fileCount":30,"integrity":"sha512-IqxlgXcErShLR0oG7R6RXoP2TzkiGrC2wcOESTbV5V5jHX+p8puLx4IKUTajWwn40l5Xj2/vtnIDnYfBKDwfmA==","signatures":[{"sig":"MEUCIAFfnhCuGb6Phg8+nfMu4PodUNCHXVaeEaLyILBgxEDdAiEAj4lfJ+ex/c6RiaPfeplT8q90qtrgcs+WQuY4CQeW6cI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125197},"main":"index.js","gitHead":"9872667f51ada6ef71fe2e6679b239596ddf351d","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.6_1636206360637_0.12890454106627702","host":"s3://npm-registry-packages"}},"5.0.7":{"name":"@hyperswarm/dht","version":"5.0.7","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.7","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"410b7edda6a74b625edc988115637ff8c2e91bde","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.7.tgz","fileCount":30,"integrity":"sha512-UUo0lVcB5u9jhjZV47j9B5LDMT1Bx7h0Ur7xZQBG2pDDheqhX4Ktgf8/W2EQUpE8rElhx2bPyfH5D6OecNXCJA==","signatures":[{"sig":"MEYCIQCJKHrF2kSCLwlJxPKIaSQ24zjAI3Um2TpyMTVpYixIvgIhAJAVB9WaSzyGO+hrbKolaaJz/9Jx0D8I+Qy3QmmKRneJ","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125197},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"14137db90d0b48e385212c07ed606e8e47fb392e","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.7_1636309568762_0.7020739195030612","host":"s3://npm-registry-packages"}},"5.0.8":{"name":"@hyperswarm/dht","version":"5.0.8","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.8","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"f03bd4f80b9abf6c168ce2c2cd9d75c4959f9915","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.8.tgz","fileCount":30,"integrity":"sha512-6yObpRT8+9nLeXiCM4SXQ+7fnLGuHKC1XE0C2i0PD6AnSZ4ZUcv7R99sAXLZJyKn1Z1Yn4fPCQnetvrGkXnNEw==","signatures":[{"sig":"MEQCIDekKeNVoTgseSY0hXwetvzwDoy4J+grw3RJWcDMh4uSAiA5diMR71XjqaITJ8zkIFddEarS32Kgs43a7kkKM1Gitg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125824,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhm6qgCRA9TVsSAnZWagAAzE4P/11JHTtl+R3tDLzPdLHo\n2Lk/qUDyd5xAZL9HNc8yMUF6F1deT6rIK9QmSidBC8xJ8DjS32mjf488wA0y\nduXsJJdITYyO+tPiiBzY/TGrMRXR9DzlY7ba19RCoLSOGHj7Gtme1vdrzKc1\npYhJWC2I4P/ZUDVP7cNZ80LscH3Aj6WVKcM5hR1nj03PQVpntdF4nIqw5WEU\nzwQw+6Ki1XNPPGKSx+cBk/DO47lFKroV5REpslZI5inOL0v/Mdvbcaou/ohg\n4waPsJcnYiN7oONM/ThQPk1pB0vAUufnwg4EBCqBJjTOJjJ//L/14PUD4nUb\nR0Pe8PrfHNSDxC4Pt6vBxQOUOBm3BKqyNdETTLbRq2B812Edo5Pk6KFPXz8+\nNKYoiLG5LFLy7YVgOb23NKhxuyQ4DMiELmX5qsZ18fjcmX5cbf2DbAA2pZPR\n9BKwEx86/63m9voHNEoD3lSWbmGzBOMNzkENGs0XMuhZBvktoMVlUUrSgPQx\nRRgUoeC2l4BWD+gmd/jxOhzXwF8r0HHw2FYR6rvSTqAxvy8shnQGf7LGwfmJ\nuG+zRa8j7ssFg8jormAAu+WI+jSQbmNNoQHa4gfkYdmtEgTy/8xMwfKhSySO\nLsU6D4ZT3ZWQqXWW609L3TFtdN8POA3rjpKLpywz+voC578i/2AFjbd0jsqW\nMzdd\r\n=XhtR\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"26dfdeff55e08c498ac8d0be227038a3ded656ac","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.8_1637591712428_0.7072145798952203","host":"s3://npm-registry-packages"}},"5.0.9":{"name":"@hyperswarm/dht","version":"5.0.9","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.9","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"921f40f9a4661873742b5c285756d55c2c5cdc4d","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.9.tgz","fileCount":30,"integrity":"sha512-SpZlz/FdXt+z3cgt4lfGytWZQPv5nN68nosp6lZyv/6Na0d9nBhY7Nm7E3PC9HsU6RrCRTlqAFvNJlKE/zVrsg==","signatures":[{"sig":"MEQCIF0LDi6dg9DVRxQLEkDhLSKJwkbVhBoGwI9q24qUkQRvAiB/Pt6enSptCvBu80WH10hcQ70phbLxI39Jax6l1Cq/tQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125919,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhp9UMCRA9TVsSAnZWagAAyCwP/jpnmf1e4PrD0cYhFRzX\nE0W0R+AZ3HwHYk/ArUyipCn7MLNiJb73kdyeYcJxKftLGqkNpBfYiIgawNnX\nC3uiuqFYvh+RY7gs1/sIcDJNMTcGgt3N75rUMJLv+ISrAe0w/Vi9IU9k+l8N\nnurQ0B9ftqhmaBxr/twWYopgf6u7CU7TKC0Wx9t8jfbLU3ZMiYBCSLc5Qcxd\n8ZkHa3QpSRtoFN7Hsf+Hl6LGH9h12qm6nvycfQ4O9xTI+FPS5RLGqK3U8ida\nIvIZqaznIIldMWKRpe5Q9wbmYgEe5gQaS6THjCvqubKv0yPpOF6uGRVpxock\nfv9SbgCaWp3YONxERai7d5PQyknsaxOGAqOOaW4tqI/GD9b9P03479aWfFtK\numehmg/NeX0hY6r829sV5dfwMzDG12vUn4I8XuuMLZ6iomLG0u7tH8TBlTF8\npK7sficRoyVO/quIMhSrZxVjttaqRXDjqh/MIOMEI/sbSF/ZRdMU9u0s1q7g\ndp1qlrQlXLt31ASwRc4wl2XLcO06gOpNFm5znvILnMg/s0bynuqTkZucsvt4\nsW8ZltIPtI3ImBq8UmsBlhScev2RxVDw1URBGRGlcQT+6gIrvV/X/vguAthG\n88jssPP10LUPTJScQZjye30v7XZ3NYwgiJ23M5vQFBK4lEe0RkkborzRQyve\nYSZW\r\n=wfXq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"3b8376a9851e80ca5d52e61383882301d97fa396","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.9_1638389004336_0.023438417540133205","host":"s3://npm-registry-packages"}},"5.0.10":{"name":"@hyperswarm/dht","version":"5.0.10","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.10","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"edd0a090fd39a0e08fc61b76a788549f250e7c3a","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.10.tgz","fileCount":30,"integrity":"sha512-gHP0sNtv+yqoTXLzIp3Ry8tl2OqiMVtWHTxdarqK2D/Xqt5VnnB/PtJZdJetHo/QNW4gQF0kcCWd9SwH807Xhg==","signatures":[{"sig":"MEYCIQDEGm8UsahGEdFfvTZqPQZgpeUyRhShsMiNiGxgU4YzYwIhAPTxuYCKG8j7/vZWXMTz4wIj1mNk+54YB6Xhhw495V1w","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125746,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhp9aOCRA9TVsSAnZWagAAptYP/3VDeXs2hDZ5EoebSDqL\nRcb9aiQLszToqX+9FdICqdPbUJcbKO6NU4GbXirwrIPC+Mx8cpDTIbvcwRlr\nPiw2UxD+ky3FP7drz+VYCOIQ6KGEnwb60eQAzS5kvxfzDq1OGEXjSk1a55ew\nXptD1eyite0aLVwZUOQwPR6DwCDqmFTQvm3wR0Bjl4rnr0k+DDAd9wYDB5V0\n2vMlfilbslRXDk/LJbuhqPgdM42lIYTMeCi6JOj+CFUsp4wJwIV3ZBVxk1jS\n99oJCQgzApTnrLvUE2KXrwJVqzCjacQ1ETCXiQ/Z5PuaBm5O8BlD4AUpOnYe\nsmViaarpEAYl1GZEyo7n6LS4To+Xvjwie5Qfcy+K3DNBPvaiYlYoelw8XU2R\neMJ8gXF19a/LpCxflDNGgQn1deR6yO0F6RoxsmsfyciMeUMfzWVcYdp09/mU\nZs/zmxnM8Ojbo9/Vi0e4ILhi8E4TlVBNhCGEeq4rwvj8D/XVt/OL1C/Vs7eT\n5w0t6LtXPFWBJ2HZewnUUFGvsMQlTUyMX3JyhEUvcZzXBgeTcgyOTSEs7dUm\nJljSOXTy9RdSTtLq88pcWUzN1FofQahHYVCeQQeQOo1d4+Qi3Wp7Y2pl4dKb\nNr/2UtmBhxWMZ3UnwpoQqapi/767gtKtvc5RgZSY0kFW1r0ftUzFvvGxw6O8\nAHDt\r\n=WKc/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"8d98224a1e0f9d9632960e2e449da24d01db14c4","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.10_1638389390409_0.33649087264788236","host":"s3://npm-registry-packages"}},"5.0.11":{"name":"@hyperswarm/dht","version":"5.0.11","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.11","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"f21ac6c72ba331caabfb518f40156fb530415fa7","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.11.tgz","fileCount":30,"integrity":"sha512-U/xE7Jf+2DcFZONtd76QHcczr7xKRYDeoFN5PIkI/BRFxpx0QQ+NxAdg+FQoYMX5tFZAKwhiK/s3s4X/ektqpQ==","signatures":[{"sig":"MEUCIQCduPvUWd/4++Uf99uIJ+wbLrVfwcloT5/pMlJrSd3VXwIgCw3j6udm691Df8/pBgecx+QqzpKxfgyncHG/IoGK0ag=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125920,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhqRKiCRA9TVsSAnZWagAA/mEQAIxEbWkorJIhctUdig9a\nkcMWGZMpZlpW39meQ88k2LMYeUKojYYddklNZ8KJ4NJ5KJ6BJSGGA0CjvjNr\nfErmOn/3UfZ7Du3y+0w0k3eEOpBZcjo3bf0s6x+lKudK00Ifg8Qy8+8i3vz9\n+1mR/jNZxxvkIQQXQcyMGnNsau/7D6TCgfFyFHwEbFdUlz2juY1d/dd+O23v\noU7+/4KBNX++voQlCyEqVTut6GhbsTGhD1tzcsE+xXrNBiLGVMuyJbmodSZX\nV890n1+SFaJtzxWqHur+X9muxHtNmI1CuAxFxpDvY4g1wJ2zbTbhLMPwj0+J\nFBkTSbOgYnSvCFQgL3SNee3xM3jtxXv7nsGJ/8YCEHETrmDcK1iIpAXTJNez\nVdLcUe0h8KOA7yI2bRL56crMrlLHfr6X+Tq16SLAkEPVBesn9seO9j7RjPg5\noQNIpZyDf3Ao7So6uGv6+IMmOSX+8xioeLosZ9Wgy4lKfVgz+8A5s2Wy0qht\no8T2zMh93NqkPsKlFaM62QAS9zIxvgyRxz+ho02rfHpCbYi379ZI2qOnAMNZ\n+zhumMlJdpYs5T/Vf9fBVAHaYRoVA/jl+/NLWKh0+/Y4CO9tDSnFW8N/Vmuy\nn156czOrhAgnnwxi9vs+Kzzr2KX2Y9PpWEixhP4umAZ/fz8nwO6dm++5WX4j\nC9g7\r\n=/iSL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"424ef5d45b396e4f9099477e6ff4dee4f3433dc2","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^1.4.3","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.11_1638470306361_0.7810769714219583","host":"s3://npm-registry-packages"}},"5.0.12":{"name":"@hyperswarm/dht","version":"5.0.12","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.12","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"7f0f772946a05e3166880b94e2ec71802b199b76","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.12.tgz","fileCount":30,"integrity":"sha512-VvMzzkAKakLaDemhhXCHYku//DBlHQ/l7e2EHTh+Z/ctBrDygU3wlAvcnBg1EA8a0qt2zH0/oTswFq3JT0WyhA==","signatures":[{"sig":"MEUCIE+O8T8WS0RJv1iNwc9BbntZ6YAm3JDmhtAb95hSfcXaAiEA2rOGIpX6OXKYM81ICNyuTI3HYSFA5TdCtRU4J2Hh6S0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":125862,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhwHeWCRA9TVsSAnZWagAAfHwP/iyoSZxGg6dFdiRNw8Xc\nfJsE6yfU85x4cy9n8PvUI5emUCEUvi0jqyMUJvIpQ7HGmUdNaQUT6f/sU6Qj\nIAxxcRPOwLN8JfZcPGdaR/iy2n2Z5gob6IJ7NGsAFMKgvew7PJ85bE1da3fO\nTrHuI/q2tA+AxRyS/2lb7tzlEQLIVSEQhx0NS1Kv37GXy6w7DyBYaw8C6f+e\n7Pm6E9/vyhr7FLKIcYgdJppDjMB1n5svSF7/acjnH6HSqv58Dz+YWUG+z78Q\ndNmx7SwPKDnjfsUJDDNWOeQtgJXYdgQfhDRtkc7+JJ7ZoLqwqcNGZ9nE2oyk\neMOqllsuc/4HhpCMZBxNLxvuGL/R4mQUX/tpQRpZD6lbfi6+Z63aemVNovb0\npXFfDMfx63l242DvDcMmvJJr/tpg5KB3svZG7GkvPxnJIjOhkGtPuXcrbWtW\nYiiOmZd7E/VU21EVrGALZ491dwMO3LRmFWLMZh1Z70PLy495fQUxR1uPP6Ud\n2a1z8DF+eQj7cYtrWJJiR4CSfY744MTO4hmiKTlOwryOh+tdc/sAQukeWMlx\n+s6eCAxycdvl4Zg6yE1pzjVohVFFonafjBfCKY+McRAW/jtu+i60Mjz9KFEi\n3MfXJiRNgJ52TLspmhICZMTvcjhM9aHhzsr+V5JKtSPlaGjqkyjAjfQST+yj\nBK4T\r\n=gTvs\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"008273991a4bab21042466a2c515fb7f0dd54e37","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.15","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.8.0","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.12_1640003477885_0.2863549256717326","host":"s3://npm-registry-packages"}},"5.0.13":{"name":"@hyperswarm/dht","version":"5.0.13","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.13","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"5cf84ef6e0773fd428c04e821b30342ea0562840","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.13.tgz","fileCount":31,"integrity":"sha512-QU0RictuJKGh2M7UeXXAi9mVtbMNTQvhW2r/IKMRZeo58faxuImzWFJjsl8AD2sLvEIJ0YItxTGNTlLSltIDqQ==","signatures":[{"sig":"MEQCICStROzU9sLuy8FWfMVw2ZAsYy93kuv7DTFK00r9nv13AiBIvHtr1IXwzV2FPI/o8wru0NauBuRRjwA/VFW0WICAlw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":131104,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+RMFCRA9TVsSAnZWagAAO44P/1+ANaJodXo/3XBhlMif\nliquxxtzB/xBqfbpEP5azyEoKRKCifP9+USLYem5rDkNDM/v3dQ4PPmalvmM\niQdQbmqr7QEXT73krGzvRjDZSlLOW8MRLvqKEmx40IEh6y84ZtM0mt+Z7l5F\npExz4kiqVrPqCktoqaQBMRlfU/Go3rrBYMlESshn8vJlr5j8KhujH0NaVdlK\nFtKWS8JhaiCdq5QBv2U5re7io0y2YbOEOI6JAJWqt+Dj0ZjzyA+Ha1ABL/M9\n6Scwfr2uET89mZzQvLixcyjz79kJLGQ9kWj1MOI1hYsu+cpdcvRNBqbnMcc4\niSFt11AOlHaZ4lX44bnuuEQpHquxvV7ZSrf2M5GHP7cf22aXMiu6yqU7tibk\nLiEk23nvdtweJWdNlJseP5kUDPUinHtRCgstuWHDbI1fuo6+YFB1xL1KTlEY\n0dYvnMTrr0bG5OI4TR08HqDLu6n3R0YHpDWzMXdHD2BsEj33eA3eTe3Wz8BO\naJtopeuKAIb/uoLk/V7DLKM9WcKapVET3PAkH+C0lJVK/zGBuLotp7CDlhrS\n3Q1Ne3aV3UjbfMf6rWPmWoPETTnK0VqT6mZVXBUW67/JLPhzOvoNAYPTN/MM\nXnws3QRetapdM/WkCIQ0DcvrlQ+A0h6sdQRqvUrJTH9AWh/eUQ6NLhW54xKq\nkiXo\r\n=O2GD\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","gitHead":"b4f122354c726308ada57e0fd9a23736a9df116d","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.1.2","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.13_1643713285075_0.4549581215793894","host":"s3://npm-registry-packages"}},"5.0.14":{"name":"@hyperswarm/dht","version":"5.0.14","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.14","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"43f50d8f6b309c39ed7d8c8f06f6c54c5665eaad","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.14.tgz","fileCount":33,"integrity":"sha512-0DH4CqusY9Tx+hrWUYDfz76HBwfD9fpWVR6+2qHo2TDYAusIBaU7HhRLjxZh+6+H7GpTFVKbYdkSd64yILT+0g==","signatures":[{"sig":"MEUCIQD6JhWV8rXptP9ojZjjmZaJ+xcbSzzxwA8cW4+C5XoBgAIgJjkiZdgVsQT0VqzFXxVPylhC3ZbuU/kydN2ZpzRuYQ0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":131508,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+kIECRA9TVsSAnZWagAA4bQQAJgDp96HAh5Wy/l+j8qB\nPhWaJp2e/2s2IL592LlXOr0KwmfiS/KJGxSqUEuBNAR943ZASAF294u/kiid\nyIBY5YI7K1vOKGf0nZzrHiaaMYikkU8mLDlADcPLRvmE1Yd/7zIMOyHJ79ZK\nGshN1sa6KDRFiQf25yZ4Mbw+blaoQech3EkzLA0d0qo1KFtpWZgA9OMtwSvg\nNunNgVEk04wyFhxTgpz3yFDehRQQZhS63uB/QbLqFThO/12PsepyVZCfvs8q\n6KNkhardp3B+VC2cat95Zam0+X2NGFoKRld1JCvXSzFBQJxYJ5jIiP96BLFd\noOFbnSiNaaVkOnzUx2O7L21BOowkO25QP58x/Pt4A5+m48TckPz5qEdaRB1q\nRPh+7I5B0ANx2OYT7c+i7X5sTkFtLDmLNDdGpU/kmmC0afLmMIkBWUCRCKxg\nS/6gRWBMX48Wep0DScQUxrAsq4QEKG1Jq2WiS/np8eCPI+oMGFp9zKV3hdD+\nbGnQcsU5cTHb3G/Td8QnAATrBpigKy4YcLelIpnoTY2ZZE1Ocf/I5zSap4X3\nAiZQCPeZqitsYIkXt8TkLBDtHJzorniyEB8OVHO4cQtF8rsUjK0kiuLGN4mn\nc6pZGBRmHLy/fxJprhVpOMDJszha9lIoFYJbUzc5AkQMX0Tx60AyGMrpKAps\nkDji\r\n=kjtX\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"69507ccf4301ca6947bd226c35fe0e3805c25e5b","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.1.2","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.14_1643790852057_0.3135334348092773","host":"s3://npm-registry-packages"}},"5.0.15":{"name":"@hyperswarm/dht","version":"5.0.15","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.15","maintainers":[{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"b157ff977c8d1ec0a1e3c15a722af7593f72bc69","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.15.tgz","fileCount":33,"integrity":"sha512-k4TeRa8w5qHEi3RPIVNbrSx7uDiiECSzdzWPdNnb6sayxRNMN1zfDpEJnHuOSUKxlVjqCx9HgC8UqCUoUxpIRA==","signatures":[{"sig":"MEUCIC2hdU0YwGwCSjW6vGGAaKSyYjvnuKd/1rVWydkkTMLcAiEAsl8/FzaQAAJvts6CRAqYSnuyTZpBfG0Xma0sjENWkqk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":131748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh+l0TCRA9TVsSAnZWagAACdgQAJ4vAQ44y5dY09riTo5B\n81I3kDZE60wDw1Jt7WGC3+hex3OcQBvsuuQ0LQibrGFyMuEmxeLsArOZ3OVq\nf5b9jgQ9+oFrY4O6OZvSLDuJEmTH0IWlsD6hskOqantwY+Ya3h5Xln1nFuSr\nyBkBMYmzzIOqEQ5jeXtoya114FzGhqYGtXytaccbQPfK8f5URyTVsiAkH3pS\nGGuISdjfzUEkQqKNxtPTs9ZCDvDizUWyKYN9I0C5oGRpGCQ+W+H0aFc1+6or\ngerjyhCzAORSif0hh7A5wSPnVpA4sB6VtCOvXnp4KU2T0izKeVRYzTBguGsG\nyAbqVYYxclEqTwG/WHfa6Tz7f7yDfd+EAoVc4x6FgQPCZpcejH1+UUwF0BNX\nmBx0hdYFU65a3WbHadyqSBLixMgna1QAEWHx6A81HE04/1jHh7uZVaAuK5sp\nY6FKdrSGeM9qWTt50lNOT3hSbMGreIWRr6rQEwEwCiC+c9uqSWqttOP89yWq\nu8DoldTNwdsTU8jmvML1tZ3AobQfJPmoAIxaFoVSIFgNKsGQ2+T98GyOg+Me\nTSyGLpQmptxuNX3I5OjgFHjFEiqVnrufi1ja01wYd0hZPVqXfixs7RL/1SgS\nHS6R84/Cd4FVrOD6mBul2P1z/wU2yZ8ELp88Cvm42y7o/l0jRAxwv235RFOQ\njvWD\r\n=o5xF\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"62346fee879901aea34ff9495a25d45ba8176cb5","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.1.2","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.15_1643797779693_0.2858431541508084","host":"s3://npm-registry-packages"}},"5.0.16":{"name":"@hyperswarm/dht","version":"5.0.16","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.16","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"741951193b3ee9f62467858e786eb6613217d540","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.16.tgz","fileCount":33,"integrity":"sha512-6kCafdH4KwiE+MySsEDhAAd0/jnwKD9eUoGRClRvwCinvuyghZDK0bA0ztF7U62dmd/SrLW/tsAhP2LvgD3ZfQ==","signatures":[{"sig":"MEQCIBmdb7HBnLcUDo7Z1MnHoEND/KJpFwhdyk4xnxGgl0uVAiAte/A8QAwJQX6i7rejXQ55hZGgkhttPL3XxLf7tC7VGQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":132955,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJiBC0rCRA9TVsSAnZWagAAVNAP/iFcja/Agqo7G5k2F9ES\nV9pB68AGhlfNuVKq1ZIBBNr5vGb9/OBFtBMfxxnwA34ZZnryPurzl9lBLvHo\nJ0VeNJRL1AAWAN/MmZcPFXvUdboE568pqkTk1ZE1u6zt/muNQZiMD6tqJUWG\nsmzSbFeEUYxj0hdvObXoEE/1ygjqOK4WoIb6DQxAexilHg4v21sce5uOLP0p\nzHYXeDjfr0E/MOtWqNzwlLoe+PBS2yBbzQUFFh4IYxSG6HzxzoP1+bqWddtd\nngPZljs7xn88alasc/m7YSEeQx2TE0CfKf20tF6qQDvsuBs2g240HxOPIZKK\nhqFwP2JHo9vAQQMQS6PCUy8G88q6sWoUXjSmUum4xwI6sJby0aFw57KIqYHl\ni7yPWcF3M9lDyrCLJBhgyNfOUd7jNeH64LCB/9WEIVMghB7jq5jqcZ8kZhwq\nzYvwZtfOi+qZ4abytXk49c3HTijYwSfSNzkt70IXKaEED29cBf4QASQcjJsW\nX/0HSVrqrl0noVfmpmro9U1v1mp2/H+XCzQXN+kz0oqz2SMSfDiBxHp6k6a/\n4/GX4IBZAoQeZTxSIYSYmUTvC7QKoCjMQNu+6mZCyA0eulu+AtQ1+w1gek2z\nOcDfuFWzfSx4gdJk7Q0EXKtWSOxRepy6yIKrjyheO7uoDjux64NfSpGbXO0x\n+TVS\r\n=CL6B\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"d898250a9a98b3dce9bdbdb45b1544b9d2f5c09a","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.1.2","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.16_1644440875491_0.10834738173165537","host":"s3://npm-registry-packages"}},"5.0.17":{"name":"@hyperswarm/dht","version":"5.0.17","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.17","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"5747ada03ff161b15eaed4bd1338087806053f34","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.17.tgz","fileCount":33,"integrity":"sha512-/ZlUSBTLR9uvzBF1V3sMzgzt8vtJp9FWikddPYYE0z0RXxpeyPkPlj+p6mLKKv66Obc4U/mYiuCc2f90vHVxcA==","signatures":[{"sig":"MEUCIQCLpBEjb7mcSWHquC6rNpO78J9eO/w3If4jzTtKojle9wIgM9p43/4e5Rl36/NTFWBgC4eef7kwDSiSCc5SoFUBsuc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":136701,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiITYWACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpJTw/8DPmPQwjNpU4bChaGiNwmCH+ZUzDVbbmwtVIiV6DtukuJ7Nui\r\nGefDJFd7/X2JPbmOOGRtIE2a0jSoaKwiVFFtinC11eyN+XQQtq55YLxkbCkP\r\na0u0ecAlLthSSCzfwztJOghkaA+xb6euJPj+k08DMdIpMdd0NKam8T68Ub45\r\n3ZC+f26SdjdHJyM0N8lvW4hqQzejADEOMSVL16b40CMG5VK5bO5hwy3w5mzm\r\nS8YVTZXKLeT+Yt64h1+5j+gZYxqmKavH4O1XoGoD7lOdHxuya/jdrsOc58sB\r\nPnqQr1iuo0GHgGgAiOFKyAnNYih4vywFOpZfXgvjzpfB2XUXcLbcl09sytcJ\r\n8ExhEU7c+/dFg5NZpSq4AnZyDYivzHIbtV/XI0yLqQHfSepnhegZGYwmhwg+\r\n642svvLFXOTbgObILs9vNS+Sl3j5iOgP+r1guhvH9X3XlS66jl+Sun6oo0po\r\nqlyPjmAVRRBePbhxbEdFfMrmNYIBJnp+7V9JxbLShAyFXJ7oyU1rZzeLnV5k\r\nFlN+i1OKVUwJSzstlDm4H5TFQdxqKddbyqaPWkE6cZxQT8N6UzgBfl+Xh1fI\r\noGnfmKTIgDQBgXqUXZ0N80RhvSJu4Y47pu8bYWsJqkIvK04K5FmFf35TQtPE\r\n4EflUL6lhSWH5JNKdo+SbGpurz9q+fHkLPk=\r\n=EHQW\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"25f878ef5fd63f3446ae2b59b6c4cdad7a2ad9a1","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.17_1646343702444_0.7043091384769993","host":"s3://npm-registry-packages"}},"5.0.18":{"name":"@hyperswarm/dht","version":"5.0.18","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.18","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"57492039776c323d959c4ce8c8b1becba57aee32","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.18.tgz","fileCount":33,"integrity":"sha512-6qo25firHM7qgtnb02qsU2c8GgZZCG9mzK5Bi9P+6PwYbQMpoyG45RAmcfzfcrHP210k2Z+JkUmnkZZlm+XjlA==","signatures":[{"sig":"MEUCIEPE3a/NxFEsufL5xqq/eMuj9d+sUTIVP0QFqsooDby/AiEAuqJGuX+fS85dnImPTFr8vQwIL1ECxs/unT1OjRA9+uI=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":137438,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiS0x1ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpGxA//Z5T7G0TxJ6Py8C69jHgqqoVn8tGmccuvi1oBOBgTVp1qw31P\r\n8LjwwzdyUoLa15WOcyNZD5N9RBmTaRl2y2kUvbtGdAobM14jtJk+S3sZ5gK7\r\nTXJN5wE0D0g0EapR+0CeJlp6yZmktGBxkXVfirsFzins6ALDPYKWNpvFFknY\r\no7bV+QmaTT1dpMbSevjJ1l14nsX6g6HeDJTXP9aqdvovqF0t67oW/Oo6yTy4\r\ni3QiaaJ/MKR8nnwJ8J6QTrRTGCou9YiTGwnSNM4BjixY0r27w3iw+zZycJpN\r\nOuSTic0D0OIWvRWq6dJnsCJeKt+91vwma/5XBQNUGN0lWTnq0k5NUeQL7JTI\r\ntksx7Q9Zl8PZxWJPrQWZ4mYjgoekxS20Cvu2ap4vfJ5lgX4K4a/Qinjw2hh2\r\no/4kE5wgEFq6wjjwbEoD0AVI2ucNVl3qUKH/OkNbgSdl0mDn3A6FP+8+oL1M\r\n5tVq2fSEsLM8OSgUmUsIgZ0kmJ/mA/LESgwQ5cCWJ5fdkyIFxQWGQYCeRGgj\r\nREAQOK2ZvE9emctqWYcQ2um5JeoHL7juviRzv4+cVdArPSjiQDnpmIIqPxHI\r\n4iHVX3IPGzRzN7l/Qfh2jhMXfrs6dC7HPCrKNq8ubRNvpHz+OfjEIgzMUAe1\r\nqz4MLWiEwIyfTEsl/Sxuf8gPI5FIok4FKl0=\r\n=JAVg\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"bea1d9caed204be88530541b003470aea9d3b297","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.18_1649101941159_0.9275150993857788","host":"s3://npm-registry-packages"}},"5.0.19":{"name":"@hyperswarm/dht","version":"5.0.19","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.19","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"e0012f11adf93a142fab94c1d61fdb86182b7bd5","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.19.tgz","fileCount":33,"integrity":"sha512-87twwUoXWWja8hxEMxo7sxFLyzh2uWG6RCcBOkFhHKRZ5xrsy3ow1dD/vm3EvGVr+Pthmr9q2LuOcNEniKujqQ==","signatures":[{"sig":"MEYCIQCxk1iKBCff3wGzxrQI9WG3V50B0QTijtDH+Vs4e6v0wgIhAPs/RZ6wFFDFFAH/XX/GN87BA1MbcuJ31iDHiPH7e3I3","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":137495,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiS0+EACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmorAg//SpcPxmVUdJTTFfmXiNHR0AqOddq2j8FZ5aQcl8zadDpJuALn\r\nHqizdtkHfQDEjt09cd7Cn4IbjAURrkz8Gllt5GGLJmV7No1xtBpX9bazB17l\r\npDJF+FRREwqV/3zqspnPYbgRqzqJsgcPJIM0rBTzik8bKCUNny1RC5jvCFsR\r\nILAWIpIjApdasZ4UdEhMishVrbNOzFUVYsjcgkhYSJZqa5DSAMwT72r9wW3P\r\nLJZjQ7SKC0B4oFTm58+rNvo4zSSVTCRygin1T/Hy0b5k5tIiSUXmKtiUV3Ju\r\nPmU+4s4FOdPqDv1Dx9YvrSb+oNUYI/hCQn+KklT8ouJ2+JwP5RMQfsPjrMwM\r\nomXmBQFwn9rToeb0+CEj21ODqIPj7BbmZdSS5VHZ0RRyrlULYWDJfoN7CKj+\r\nNoZduhfa6X6Ahj0SMmiCCYivyNV30ND22KIcP7SQ3wGCnhvElbGen0mr+6Sb\r\nIZz4y/O082WppjfdzQsf0nX+vo1zoeqhP/n+zY+Sh8mYr04gJYVaI4Qb54aJ\r\nPtqx1T5MqyPA4DMmVBdbGMSOzPvzuqQe4l6f/ROjLKffB3stOqKkcN1KyHEY\r\nXI0RFgZXtmJOIPial4MvAgGd2+IbFCoDYMsXdMzclTE6pOcIF1zGBBoGGxrd\r\nAOTmBowmNchD4bOkBHJjIucNODpbMLtmOhQ=\r\n=UUPS\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"2ef0087970b8096a74971d233c94dda6a5a923b0","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.19_1649102724409_0.19694282225373527","host":"s3://npm-registry-packages"}},"5.0.20":{"name":"@hyperswarm/dht","version":"5.0.20","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.20","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"a2347af80ab79207a1d101195e905cd6b23fba92","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.20.tgz","fileCount":33,"integrity":"sha512-7iwz+6jcaHyHUc2GSKkyKk01k2ZUp4Bd/6/GzKTC7EY1Tj/9ePsUa1fpG+yKQSwdHGZFKnRjeFmYApUSjctnXQ==","signatures":[{"sig":"MEUCIQDvcgqAK48pd1bpBI+wFfp75MmUYmzHzXU8vkfD/kMoOAIgZWRkYFt0QXYwPaw9TY8Y2RX6YOhFnGt0L3W5qbrOVSk=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":137568,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTAaMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqpog/+PgPJofejvcuezGvXV/xGNO5ksucoeCkK3eyGzghNsbfMNFX9\r\nW7tEc+JMxTm+xoT4xE/k3OeXlKxqBGgjOZHJoeQaJmbE22+PElE1AdOEAvEc\r\np/zPrfujGJMZsZ338r0aWlWkBp3/BwSQZL3H9E++on7sWn+AtRMMhSQNSCBK\r\nrDl+OXeEBU6nJ7H8of0txzla2Yk23S0afBWwFb5DqZXrAKvqx/zuCSODKpB+\r\nQBpST5mOR8BdUhAV/h6zEpOgGK6YvLVopIDW0JZJg1FNmpujpK2b9K4ygKOl\r\nqXuOVRjzgEmOiHaMhFe9D49HQWX87FFKN0jJ+w0Y2gN8jV/6vRkJ9gW23iM3\r\nU7Q7F+jn/Roib0aWaHhfJ85dFbb4KQhWqSVBuid+f8bwu+9uM4CU+X7WBThf\r\n2MReRgxWN/cZCnKzo5/muVnxb/QXtHSvQN7g7GIUtWa4YPDmgy/u7W8UmDUS\r\nhoKBDGBV1Sd91Zm33jucY/ZPNBbtdSeItPhkcwwrYy+8THO2em6Nv3ydcfBO\r\n7sg3Xtcf7A5Qxp0W/6mvw7ZW1PiYTNG3zFZjx05Fip8W/RanIbyxCeWYtsjN\r\nOsq+YsMdMmHS0bgZElM3KLvwQOe7uTf0uv2lf6yFCz6mftAdrityL/WOg9tY\r\npJyNZOO6ML57x4qn0n7/qCQgdKiquXoWV8w=\r\n=dmFq\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"880f46e52c761c3d2e10c67e44ce8efc1d2cf79c","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.20_1649149580173_0.9305149468428504","host":"s3://npm-registry-packages"}},"5.0.21":{"name":"@hyperswarm/dht","version":"5.0.21","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.21","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"a6245241cf0d153e08aaad6d5e0f35c9e123b7fc","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.21.tgz","fileCount":33,"integrity":"sha512-9DcP9blGqrdYROKKziNZMxwA2sX0Dkm/3NZacyoUiRnWjVmc/V4dMiZnZMZ1Xhx9ZhzzCzCBRDKqywkcaj7wIA==","signatures":[{"sig":"MEQCIAa3oViKl/Y81C9FlZI3fX2FyMBqJXsm2yk9Tbcq2XYaAiASkml5cy5q/9xo3krQykt3BULmbsEWT/34mxMLdk8dIw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":138021,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTE6UACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrNLBAAm1Qjj2nZXsQ25wNDvrE1Ggw2ZsVHPzGVhu4b/JbEOAOlmd5B\r\ndTk33o3pVCJD+BR2YqI17Ocd3lF1E4d8eH9NuZOHo8VcvcR8jHqxUz8WKVti\r\nFiXZDrxWqMgVi4PuUX7jlMYgJl4YXzTKOx9YZ7LLSi3mOFLcfptjBwnrPRe+\r\nq4JH7h5//6a0ofSaKGph7QLOMmQm5DDUX0Fe8LP5/zH3t9HXx5PuMPRj8bRo\r\nWQ8hudASd0Z9CRbq0Na7mDr8QBcZxWkBVR1RhvI5OLV/8ZULpDRThaGcBV57\r\n7SqtkFpMU1/lSfYzzImjgc/ZIlS7oS3kpxwpwwDI4l91I8Sj+f349xwYjPyL\r\ndr6ouCya2GWe7C9uRLWHz91o801cp0IQNKjUQsu4m6ReHf63ULnU8AOR1p02\r\nJ7dgO5BQhqUPUySnHkKwxpaNIs51RUJ547mjFG+hFSirdVojCUV3tsI3sJS/\r\n8/uDZN3TwPgGMxg3QBNjtyqX+Ew5njW6iSeDr2wZblcYaS1X/fYQ8g7HIxlM\r\nhFqCiUrLhoKTdmS2bDfs6YBsyrMv6b3ojWtssD3xhIaGau7ejJ7t0nl+B8i0\r\n5IQVA+MctLkrwJ+Obpmzu66ZqRx7zZeSHl8zSEQqoxpyrArGpaUDFcU6n+Ys\r\nfrQ2Y7BzhNCVmQCjfIuwR+BBc1UoL8jY0ok=\r\n=ibp2\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"20ed82f56f99fcda9a1a989fcaa97f20e685b775","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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":"^1.0.0","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.21_1649168020489_0.5802261449219484","host":"s3://npm-registry-packages"}},"5.0.22":{"name":"@hyperswarm/dht","version":"5.0.22","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.22","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"21b509d10286ac54c126253d89ec1b4824c8983f","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.22.tgz","fileCount":33,"integrity":"sha512-YF5EzXD5n7lEx1ULGqRKxYcM79txF/3P93LxRMxZ+YwyNJTDwe+pIPliKCNgmocrZgbL3KpUWIUb+J4XJJsj1g==","signatures":[{"sig":"MEUCIGoa7dZ+NgkR3v5kectirPxVENxV4D3Y//OrjLnrN1qMAiEAsSDBdgbbpGo6p+/m7RfGFfpEJA3/rnuNkUttLKeHVWs=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":138495,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTFm5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoLMA/+IMmAN7+0dNZKCXq7tamtMCvaofjW66V9z11nXuU9ICeZI3JI\r\nPdSSiyeX8DE/dV+Z4dcYUnAnxCE249IlU5KfJlJX0sVIvDAMfEirRnvxfXAn\r\ndsznbbFZOeA0xMuiBaLJBdmwtWWPX5kHhBez8Wk8yiKPtgWD4EmegUZEoRWi\r\nxbpsc/KR43DO65Add5V7J3/ig3j0VhOzBJ+wUbHZgmi5pV5u/RxaO0dCzVTm\r\n4dXbMzoBLHRblZArJ2nyFzfxMyNKsjEqhDuyvHKAZsDevYryRAd2+6pIWUEp\r\nCOHDo7FA6475BWVrXUZOeXRA8WK89hDmQ95Lnw7/ixAoT8sQQ6AjFrBo7Iy0\r\n3k++EXvt8sv+VMmeUpT9EIzXdVy7gFwmhL/ONV9A0bKJuXDLkB4y/6HKxeP4\r\nNphG8HSJt6xHG6cGBweYBtJ00u0QF3wa+QPAaWfpXpohRh2l5lHQwltatJlx\r\nN8QqEx+QCNXnFP6+PSSPa/QR2Y7gVHxfmR67wS+yPtp8LcXVvmQiDHELdJxl\r\ntgaMvOW2R5cAeIBs43G69i00HJAJON9YF2KLVWC8AtT76VE4hsTJ8C9rYbpW\r\ntCBtptQOoWsANQ9fTt4mHbEqGGFj6LYHUPXhKCq7A4xALVvB+gPKysYR52Et\r\nFbMMI9z08wR23phuXr2CNmuqqK71jxLjb40=\r\n=5z4V\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"9fcdf180c70da36afef375e5ee838d8e6807b606","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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":"^1.0.0","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.22_1649170873582_0.5877261181292974","host":"s3://npm-registry-packages"}},"5.0.23":{"name":"@hyperswarm/dht","version":"5.0.23","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.23","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"8c9b7800d6d9b005d55072543c1ddf45419357ac","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.23.tgz","fileCount":33,"integrity":"sha512-OWjyjs0WV2CAw+TiFT/BVxZ/CrKJOsqPJa4vFLCHZWT//UTW+xEb5fedIuRU74MPvsaQFciwfgGZ6BvqOaKDxw==","signatures":[{"sig":"MEYCIQDqAfgBjVXChpvqXx8U3eQuP50533chhaU3o9FzM34tDAIhAI+tiEfd1vRN1mGTi6Q9OnuoKd/gzTxj5ez6dcYurQ0j","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":138495,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTFzAACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpXdw/+N0YmAS24sTKGmeo8f0zc6aw7wbDUhdeTj47JxPIZrH+CAb01\r\nMwGz8hGssfvpcvHjOBUo93TXFIWpkN4RFt7AmRah1oewhsvUQ4zZ5BFxRhVK\r\n7X9tv68JEFGbs/xJjOYDNtNhjf1W1TlaH8UN8OENvqRM9xq5FTWuW9WFxaeG\r\nhgMQah7vv4g4mBmtmCM1BH2yPDxv06dngDNMZ+c2RQAGDNxzT29JDN9kHCdi\r\n6Cxyge7Tf3O6kv8E6FbgyUqDtIzZ2m3d9R7Ict/R3rK+nhhyZP0CmcqWb7cf\r\n/5V3qZ6x4trCb3zkirMqPEbWac20eFCpRKrukrq6Ja4PAmrw4eC0/U7Hba+B\r\nMicf0wyrcUbGCv3QLI5intjy/MMfwZztV6TSIvMmim23LWdhORD/RE5Ainvj\r\ne8ES5hOBtojRWm7QmOxKyUv7MV8kbb8GRae7CJJl2B7M2087O0m3b7+MrJ2k\r\nJBICfB/X2vAmtcJSJvKcSnXEHWjiUo3wb2ALIWbak5zKQ/Esym96uFFeg+Lm\r\n8oqN0T8cpkEEzlOeLCmblWJdCsBUXgzv72ffVPZRiDE5y3l53Ympcw5+WGU+\r\npqgQMrd8DtHCxXof2sImQflEsn1n9KKzM8rmgHH+JTFNQa6EzdrwDxM1/mKF\r\n9rx6C53WriORIotzZanjxSMooVzNfH0kPFQ=\r\n=4aMw\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"8c92ff3b4b21ae6d0cb1e66001e813d1d4180601","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.23_1649171648311_0.0814276761324697","host":"s3://npm-registry-packages"}},"5.0.24":{"name":"@hyperswarm/dht","version":"5.0.24","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.24","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"f5fa88ca0ad2c84b878b021607d11f05d3780d0c","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.24.tgz","fileCount":33,"integrity":"sha512-ODi16mCbPQAIgRm5caELNr0R+j/6rLb7/2jAtknlvHqVtDcwtF2sg3hNe8O1sNG2nMn6DDoW8APmpe5roF5gvQ==","signatures":[{"sig":"MEUCIAfhOp6yjo4HNYNwUEhBbm/+gShe4mHgCsk9GOaO7ZW0AiEAnGdTt5xkLbXhlQ9hkmmic04dD/SlYLSeCCdARyEGS+c=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":138640,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJiTuIeACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrBWA//S97m8yTp6p8X0wM0FE7x0VnN8qoXCpgaWC/tcEdSuVDAP6+v\r\nynwUI7+G7TqiK5+vZepOGbzey2yyTHmzXuAoPAzLbmix5Hal11CUhlb9nwWv\r\n2yM+X0ArlZ+EYXkpN7nPw2pjRaKbq2ZDaDOFDbBoRI2soIWtfZ0Lfmxb0Mz9\r\nwJy+CyX2N4oLXcE1zBxb3reX6ouy+Ub2rjChE6Buv72xeZvuqPgixR0GuquJ\r\nsv9Txx2TqOEtR1QCKJagyyr0oq9MZl/454oSswZ1xzSJBvNf8Ph+xGpx/4Gz\r\nuEGn9bAKQpzYrGM8Rsr4lo3uRoWHw+4hOQD2QWAqa83gkb88OoKLqbyk/Krb\r\nXDFHn+9tsWXOhqgEIZSI1Hgy5Ve7dhNKB4FJwG0hICxUg7IOJev3ZIFVB8Ik\r\nxD+oWND89c8+h1bfBl1/vjMRLYnLNCaZWsfPPUKlUNfa+kpfLhG6HsnoHnD5\r\nSqPFlR5/yPIuPkw1jnw5qKE8bNi7XVDj0a0r/+mJXBQdthLMix6QaU++CO1T\r\nXOtQ3yp+DA3tOqfrxHQpYmbIcCtNALm+s+SX7zUQ0MDEc6OORGKtl6RL107g\r\nba9jgh0yfrLN+gDTMgYGyXXpXfoYPUlJ/aSAh/HQ6OQO15jOQCdlvc4ZETyE\r\nosZhbk6xswSTOaHp6xDbLSBERZTY6eKH4U4=\r\n=noA1\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"f3f6b381be30a2d1dee3f08c27335d1466f2e4d2","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.24_1649336861898_0.4588545676382545","host":"s3://npm-registry-packages"}},"5.0.25":{"name":"@hyperswarm/dht","version":"5.0.25","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@5.0.25","maintainers":[{"name":"kasperisager","email":"kasperisager@gmail.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"pfrazee","email":"pfrazee@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"dist":{"shasum":"eb9f4c314715723ed7e7dcec2b3dbe2722fddda2","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-5.0.25.tgz","fileCount":33,"integrity":"sha512-x8Fpvp96NSb3M/0Fap2rm70obpNd0fe8oJnwZxJfIvxQtItYFVCrD8URsI+0Fxt4tNINMxnE9h3MaKoaxePP2A==","signatures":[{"sig":"MEYCIQD4joMPFrHN1byhIuO7A2sWXG9WdG2V+IEQD+HKfIbmlwIhAPqCWENsU2Jo2AvJFEEBV2KLgLw6JB7yXccXTZBMwhL5","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":138701,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJia7UzACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo7fhAAk8Dz9mqRZa+HFzdUFlzJiemIVB9KuFmqbO8FWYfTFnRNuc4E\r\nYybKBwo+a453EnF2MSkT5bzqajla+dNTqNSjDvddTWtoJzMs6zTFZJ+EsRPd\r\nxcEk7yZG4YY6yC0B6Q5oiSFcM0de/vryJimY/Z/u5aA5DW9TDqw5v7Go05/y\r\nnhyMBMLaI7QyfXKqnzLvqG4SBRRT/DGz8Su+xbF1Y3TLsiITffQDLJl9xSFo\r\nIg94s/F8Nwf7pBUm1E8GRS7wfN4yxEpbX88xZWd0UuUIsq969lGBHqo/oRC/\r\nbK6MjigpT2e5lLM9Wii8mAs2XgWZpn+qaeDJ5kz5MrJOhTi7pgFWJyQLihm/\r\nEDpMgIDIg/hKAHR5lfI36lbTCG1cQlftQW6kRIDmTxYIPQcLwuoBD+yPw64Z\r\nNJvMj8O9RFoyl6S5jEfn1QlF0PqndSi+jaNvD2GCBuFEDGbMfJm7Int8+FUs\r\nFLg/MACt4imwSf2xEXiv9CUCLG5l3vDkN9ij+DpqdFN+p49oGkBel85rgl/S\r\nS1tUTGhyft5rSN29CGkfQULJO5l9Nx+UWFjL6TSFPTLcFZBd41qjqpoG1K14\r\n4WMPe6XOwqCVzpBwz4gPNWT3bIcKEEa8ElcLSjJIhFGNlXXlpQxQxKauB1OT\r\npi6kMimatoK0/hdfEJbnZpaPiS35roYClTQ=\r\n=k4r5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","readme":"# @hyperswarm/dht\n\nThe DHT powering the HyperSwarm network\n\n```\nnpm install @hyperswarm/dht@next\n```\n\nBuilt on top of [dht-rpc](https://github.com/mafintosh/dht-rpc).\n\nThe Hyperswarm DHT uses a series of hole punching 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## NOTE: v5\n\nNote that this is the README for v5 which is tagged under next.\nTo see the v4 documentation/code go to https://github.com/hyperswarm/dht/tree/v4\n\nAs v5 fully matures over the next month it will be shifted to npm latest.\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\n  // Defaults to ['testnet1.hyperdht.org:49736', 'testnet2.hyperdht.org:49736', 'testnet3.hyperdht.org:49736']\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(bind, [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.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, using the [@hyperswarm/cli](https://github.com/hyperswarm/cli) package:\n\n```sh\nnpm install -g @hyperswarm/cli\nhyperswarm-dht # runs a DHT node\n```\n\n## License\n\nMIT\n","browser":"browser.js","gitHead":"180bcaf5612afa291dbd83327c583f0d97d5bb0c","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"6.14.16","description":"The DHT powering the HyperSwarm stack","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.13.2","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.0.0","dht-rpc":"^5.0.1","bind-easy":"^1.0.1","utp-native":"^2.5.3","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","sodium-universal":"^3.0.4","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^5.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_5.0.25_1651225907329_0.6380868787642107","host":"s3://npm-registry-packages"}},"6.0.0":{"name":"@hyperswarm/dht","version":"6.0.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.0.0","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"d71cd4f63bf1b3621de6fcb749ccbbd5c9bfe7e2","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.0.0.tgz","fileCount":35,"integrity":"sha512-LzkGOObqlv7yQnged1EgIHHD1SaM9JRyAiURAMdjPROtCxN7812vLwFoKcjmzNsykZIGkAVQ426bU4/c3HaoBQ==","signatures":[{"sig":"MEYCIQDDNrdKLqR+SAcPVWzj9P0L18bWGUyP0mRu7C4pNdp5VQIhAIdvI8fNq/+Y8uy0gjAkv6hmqDwqeNOwUI+21J8H8+u1","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":133034,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJircRMACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmqv1Q/+LrIZmt1hEcjUwSaFbOHGDMKWqsJbpdvRH5/4xfD2IEELocer\r\n/7dxxr8lXdcdwF77FQqJdkor222c79Itsd4hnTwTBlXaYX/wfEAX28NOnW7Y\r\nhyMZZwcUsnDCWmSObhDhDiQxee5Vi9JCs9TcMeKvI7v+wq2idBjpSsaBciEp\r\nqNAwiND95yBYf9peDF4/p+W/eyRB66n0rDvYE7JiOknq6sQluy4xCMN/f/uw\r\nf+kdC3p/b0ZuktyZiaDH9k5BmWKlhEFsN2SEDN5j+rjyCJeBwvP5Oht77DfY\r\ncuKdUyEYZJk9mYZEum0aAkCsrRuzkl1Mm1gKfYEDAKEG+uZR8Qi1e8rghkH3\r\n7qnWJw5ghYPDcumMINafrS0sqxf83aHFWbEa01diWSiAUw4MJO662INU1Te1\r\nTuaVvPykAEnYiBoTisWdA1xmBg54jdlFYhtrW2+uVs6c+i9njrgjTS+SRXKv\r\nM0quHeefVbhnVM1I2HspouS5PB0yd4CroY0tlTs+aDjcrVQJxoQlVFcUbp2W\r\nxBmrLiGMEE5tMesMeugTyF+uRaCOkXHQc7iS5TWM/eUxP0VG+ORsrjD95SAZ\r\nEsJ8IQi+cXnsodFSx67VV+J7OHvumnufjm8JchA1NAoqUlsizvblC5zmcOQ/\r\nDdsSLbt+GlxEpQNyoJfWKEt5qwdvUNcM2fE=\r\n=r77s\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","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":"bb21a0191c1d96a727dcf82ffe3cb8967fb7c474","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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.0_1655555148222_0.7937976256721291","host":"s3://npm-registry-packages"}},"6.0.1":{"name":"@hyperswarm/dht","version":"6.0.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.0.1","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"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","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","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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"}},"6.0.2":{"name":"@hyperswarm/dht","version":"6.0.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.0.2","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"30c4c9d9be5e58c7e4313914caf6a8c13e2a79b3","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.0.2.tgz","fileCount":35,"integrity":"sha512-3DfxLhxsnKuVX6ZwekaE8Yju40p99kqGdLYl5zRbG179g2RkbJP9Q8GGVIOLaUPH0g96Pn2ZJaPoQVbNsXEI+A==","signatures":[{"sig":"MEQCIBq8uVmHn3KGFfu4Ei2HuirNrbP56xT6ZX/lgAK4r8hMAiBe+W5hxRbRpwake9OLv3HY82y5GygHvKmrO6tm81rmBQ==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":133436,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJivJIbACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqfjA//fzQsTfvybKdXZNpQiV9fl0gaRJubxWLbiT0xzNKA7Z1Ux2lh\r\nGA8I8TFtbnVLPylknUDQpo6uyodoGhlTUYKQDRZLMKcXD0uP6okqtY1PnU2O\r\nx1p4wCKowD4x8l1N8siVYxiT+2lNoxiIJiz3HWOFJNlN9nDfyeInSJ7kYrjg\r\nJWK58ICodQoGMMBhQYGEbh6Dnled3qnW3VJsDKpqA/V6MAr45KsTXQvaYJzD\r\nZ1VXpQhM/p/HekDvGNAk3D9gMomTDSjv6cbObG8iPcwJlEk6XLq/g68nV23m\r\nP18SJkxkv3vX3jksjVa8aL3a1JIq+p/bdqYYbEHZxtpbR0Gc5nJxij14JrX6\r\nfGersZ6hZTcR4cKt5C9LxzecRDkEJxMlvsJgbkNZ+BKQLHGC1VEMWpbZmN5/\r\nrcUNO+mlfCETAAAyHK1uSiIUynJAclhPCQOeGRubnw5SQa3VnAwFj6Y0d8ks\r\nlpNV5yDdI+nl9fhtacOUUX75uoaEEhywacOF8GmyuIkDHNp33EyQpVTn4wVW\r\nI6lq+bba0uOx6xXmHObDKlNyuiBTelnNinpL5JEasSbHk9t8MTSuc2ouBOID\r\nPt866hcJxS/mADofkMnbYdR8djMBsGwepWif9qUe5IaGC5KtEh0q0t3v8+uk\r\n8efiSTmHFX0pplG6U+OEu+2kcuoBp61h+OU=\r\n=opVC\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"5257dca0f242207044b4d4149154ecfe2903a956","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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,"devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.0.2_1656525338911_0.07526627192212487","host":"s3://npm-registry-packages"}},"6.1.0":{"name":"@hyperswarm/dht","version":"6.1.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.1.0","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"33def4864b1090243856b793df4e0d343443c7cc","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.1.0.tgz","fileCount":35,"integrity":"sha512-ug+ykkH33hKhYiJj0tWjqnUEMtqfDqQTlIvmR4RbMVaF7dxQYR+Z3IYJUmXVMW9tdah8D4Xq0iDKbQzfPpRfFg==","signatures":[{"sig":"MEUCIFiK1YV15DrSzPhQ9s2OMkTz43Tn8uo2ixqfYQOcirOpAiEAqlSavLUPsXP0W23HnMRsbVMP6lqa9LQdJt/GOxs1thE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":138714,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixAL8ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmq65A/8CjUclkeyQLPEEign9F4NScBSTl6oVJHHMV3vIQJalK8gqGf/\r\nloz4DlLqgibq5IO6CYmgVBZHOV4A6YVNFNCPc6uMlhEboFkNPHzHnqhaK3fZ\r\n9ZVLDtKwYKaRGBmFTNyIZ0YaYRc2oZVachtloYUvyv2nTi7Qx7RCRkfYhktB\r\nUsnM9y9RsTzFkGtwir0r0T9Piv0YrALGL0Nd8/29NLVUFK3KVvqqA7LimY+M\r\nsseMSGNQElPo4YVuy202NbPjrT1OPfQwSIlks04539cojJfwFTKG5fjGdPQI\r\nUPm+3m3W/RMFxHeWft1Dn4Mwtt5rdNofjWrurZC//G8i65N3Gu3D9GpKw9cc\r\nacsvWRIwxhR/ia1bXDxwP/DShi0SY34olNPIcM+aGqeZGhUoGcjL9/IJawSx\r\nK7WWs+RkcisSMfK00g+4Wbb7sqo+yq/lfBiNYW50m0s99uEnz2XmLaHoJm4+\r\nK/Z581MSkYvFjqg4mEBmC4v5lUOQLqSL5VTofx1xGFLxSFDUvc/C6o2ki3YJ\r\nKygIcwHSfxUsu9OMbSXriLi8m0SrAvCmvt2ZB+j8I2lnJPjJeVK5ZZr6pxAF\r\nZxoZPosQ0+fgrOM/+Zwjdre8CnAp0mPVt4W/UizOTcs5V+7N1otbflWMgevk\r\nuR1bU+88EeIRE9qXLcd+WbM2s2uFiMhrq7o=\r\n=/AAt\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"c4caa43c298e3c9f26fdd926e3d30abcb1c7ff26","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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,"devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.1.0_1657012987868_0.5171253711527346","host":"s3://npm-registry-packages"}},"6.1.1":{"name":"@hyperswarm/dht","version":"6.1.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.1.1","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"e14bb171a8fbfbab36e665b742949753316e3c87","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.1.1.tgz","fileCount":35,"integrity":"sha512-rhszftFpNjEwwqRxuEEFOfvsXWIdghAESQpVgMIshYBYUpBKole0jdwcGDa8eDNqRnIefgjr/vtMZHV8GMnpqQ==","signatures":[{"sig":"MEUCIQDzfNUcW3BwToNABCu7/IG1Zt6zL6syVvtHinDjjnm7UgIgVK229GImZg58yks5kle2XU1KCPKRIKteg76/AA36XaE=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":139135,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixCP7ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqGcA//Rw8gx+aB54IXHUrgAFypdg9DJTmK+e6tFAES0yiOWJm2oMXq\r\nDL3bV/8PKrOTPldKuUTOVTDFSrFByRA9Mzxp47zUVdUcZxOu5JDAthbKvEKB\r\nfJHFVnR738VLdMZDKNxacvVTTGrHyYFbQQyhKNF8FiROulTQd5r8UEo1DpD8\r\n4uMWyV+ByiiNOHeWvaq63G+h/8IvULtqeBykswac6NOGAufD3sqIXWWp6wYD\r\nyITk1ZOH/GhJATZv3mSJIkQqvKh+ZETirPoVDaYH/bYWU/CRZFzIv73FQKKk\r\nIYmdZiFtjXxBxuZ3c3M+t6Kesgo8j+hHMoh6ZJsC5Z0mB60o2iN9a86ziNRy\r\nKpzSmiZCBiPIolAErMkxVd+Zb0hzy2X4/Y9HwGvpLLW3aIYgGnVpI3KJspT+\r\nWPMRhiea1B1sKzpbJrwwEMCwBwUskEKeDIJ4TxLrgI6Ur4MFheOuCsLuCpYN\r\nWicBPEVlO89OIBekQYAlHGMbmka00qi1g1Gf6HSqq5WLyWy2x8kaqWB/Ffag\r\nuWBUVQdMqJC+XJ0rofqbKFLcnRZ1vdoEZKitOxAt33kk1IAJVDwWT+LfckEW\r\n9A/TUqNLvduW9J9UATCNjM/sJGcT6nxFfBOy2Yll0VGoovS5DiomXCn5326z\r\ndndWkKxkJ1n7rWrt8V2U0E9K3eGtdjaaI6Y=\r\n=HyDw\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"3737dcb29af3ea31b5a8cb7b051b07d85321dd98","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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,"devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.1.1_1657021435814_0.48910591253180824","host":"s3://npm-registry-packages"}},"6.1.2":{"name":"@hyperswarm/dht","version":"6.1.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.1.2","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"dad5ff4a1859b98dce6fffc63ecb717617c9cec6","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.1.2.tgz","fileCount":35,"integrity":"sha512-Dtw4XoTh9y9E0wGBHEtjzZ4Hhx3Avxp1HMtkkVXyNCCWm+7kf2NdeabjPgrGViPYJrIWK3VPAPq36oW74bZ8Wg==","signatures":[{"sig":"MEYCIQCya4GROa6TUs2LW+PL9MhjXRmBb5+6NqbYB1SFDDc3tAIhAKlNKN1MScSMX6gVUjcVkMazqvc8knFQmoI8W6HVtc1H","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":139080,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixIhQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoEpQ//cggJIGU1XCmwLAuE4vjgrUjs5t0KOEA6uNhePF4WcvamGp2w\r\nMkstNs9ZV0zmrSphM5xD2iOt3vqxGl/BqvIsaVscOkHjvxpPVd6JUapJ9vhK\r\ngHnfepftb6u5q+qF8WHBHhTFrD3oIpeLKZqarqIK5UxrqubJ+AoAmuPDLnVs\r\nt33BGuW+sseCBSwRhyvJPVZBit7sHBEkkYR9EJ9kuEMcUls7QUxSq0k/Gtdt\r\nN0upRXitQp98cw45JHHIQhlkd8lN1aRCZVrJmfGVOiNE6P/0YTi10Dcs7RMA\r\nf7nrGrVH+bCFzweW/V5g/VCXXZSHs+A/PhKtp8jfQ2IRHkJtU7KEUXej8uNb\r\nLatmU18P5NG5qyVnibD32VspM/PXTtrJx7whiLE9PFOXSHziSVIkD2pkJj4w\r\nqCnu3KtSOM6U6PTTcmKaMqVKka43+coQq7ofcAU/x1vvC1lPGSj5lFC+UL4S\r\nbrP1NUPNQFk5HkWfljN5l4SdzdUQzJRR8SmDVtKG+tcBORSljCJ5u9K+MOI5\r\nBwc2BZrIH9sR8JHYeb0YiuxiklxV1sqme2drKX0SXHHtQjIB5vjgYbvJmIII\r\nf8G955zH9hHF80maepU0RCR/US/dWrBKPkhvBGwcJkOXbKqzmPPAckmGHMCd\r\n5yI4Ow7QZ5g2qmLIoQq69Udb69oQRatbVg4=\r\n=WR4n\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"9976a7c2c1fe2ef083999174ebd25f70110e311e","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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,"devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.1.2_1657047120458_0.0727626368540204","host":"s3://npm-registry-packages"}},"6.2.0":{"name":"@hyperswarm/dht","version":"6.2.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.2.0","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"b2cb1218752b52fabb66f304e73448a108d1effd","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.2.0.tgz","fileCount":35,"integrity":"sha512-AeyfRdAkfCz/J3vTC4rdpzEpT7xQ+tls87Zpzw9Py3VGUZD8hMT7pr43OOdkCBNvcln6K/5/Lxhnq5lBkzH3yw==","signatures":[{"sig":"MEUCIQCGPqsS7H/zIEBguu28TN6+AUmBfG58P4KfvPgGcVEdqwIgV4MD0pc+zqByI8wbzxEg205QXJ1khg8mPBKOrLhE2Kc=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":139740,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJixKq+ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmriCRAAipDZXhoLT8l2wKDCJHBJnMHIwJAhRDsKHR8b5KbtwtP0Xowk\r\n0aEAF1CDY78OwM83lsveOgAiKFIE11hCI8MAhyux6UZ9L3yFdbX4LWDEqJsm\r\nJ2CHI8+PpCgP9yufaLD/lpR6bD3qKOczsrWFpOfuZbqeuU4sHchdMqORdY94\r\nPdgSaAqDizewIqqDU0VZWLrA96KSdPt1cgsvc6/xY6PuWFdGc3mwETLTMs12\r\n8KJ13ZCJ/dOlzGR028ymg4mXazBjnnWqv0QBgnSVobfKlVbY1DuJ8QBaXxnk\r\nH1spWXzyzydGRKPpniNkCq/iH7DUzCuNlrYT9LTFDAzCfIoveNZwIzzrGdqg\r\nPACHnQgAZ1HmhGbTxupQjpyhmsZzE3uguH9oZotAm1IThbNu13H+QBTI7U/F\r\nyONRUzgdsyKTFV8zswm+nabpenTe41YGZlRDFd1ZZ9EmdJNLaLlo91gmmSR0\r\nIwsyQxnISjv9pvq257BRy3cgf3rjL7/Dlu2Pc9VpWAkDJWogET34UV+0kGTc\r\niF7T5ps7TLm0xayrHFf5vmnvM+H8bGWkTIe5YHB3h6BiQjgNJ9u0CfhC7rCX\r\nP1Ay1/rDSiGYS4Xtp2jRAdVumAXIUKS48v7+PNjBJfyw6tjK6qzie/l3PEeD\r\n5SMZ8JvOClI40/6HrUmv2Rk38nRxo45D5po=\r\n=3nYm\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"0166dbc934ddec53f414e4e622b338e49bd76730","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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,"devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.2.0_1657055934062_0.053537479013920475","host":"s3://npm-registry-packages"}},"6.2.1":{"name":"@hyperswarm/dht","version":"6.2.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.2.1","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"5f9942dcf9603d3d85e5c3ddf1f7a964afbebc69","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.2.1.tgz","fileCount":35,"integrity":"sha512-UsDpb8A0jlN4uEft3Jwbc44lsdfxPGTAB9fLHNWY8wp1XHkHAYLLc/JIvqo07rgQSm8gQIXZJ2EDs7e9sKvdHQ==","signatures":[{"sig":"MEYCIQC4FrazxnEeRG+3qf5mES8u/rhXkOy6wDF99UJE9TKkIwIhAMUOfh0wBcVZgcHEs+Al1xUh1yixbaIX6ThTrL6tSlcd","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":139929,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJi2FKLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpObxAAjxJNoFjbcFGtIIYGLBxUcj8lku4ajYJvR2DbZLNVTjLu+cD8\r\nBTsRVcDIiiKgCSTwiiYNm1P2P28s16HN+d030E6ZLWyoWzpSsXcethIU4aaC\r\n30ziE9WleJfXDcHZ3ChSPGkUIVRYwvNKAuZjAzbzBxp2zW8U8NpQ5zEJSLqZ\r\n7Oo2s7nJNK/cLVxBRPZ+GyBkZTIVoUKHaRN6TqKZFxbLnnS2nqhPWSreQYFX\r\nf5nWzby28ZTccaPa2cb8i2L/A8mXrQqBplSLVoifwZoZsxNGMCQ7XOLwMmRR\r\nVF7tmZlqP0qES8r0dJxV8QHFwtiFv9Hqqk6vJ6GGDTITtaw54MpuyOhDzuLq\r\n3Vjr0Frnx8zSs9kF//SsRIQh4XpCeZRSePD65dMu5HicNW4nMC07bQ/aBeXB\r\n159ubj7JpmeCiXE/DgtFwRbjSN2b26LuNy+bVOS3WltorFqZCEigfid/4exK\r\njzSNShel+4AGHLAz8vpvefPOp8dokgF9xcQwjmYhcV5xUvBcOBL5g6a0VNbS\r\nwK1a+7V1bDRxMgw0riAJTFfRqDjNBpQHeaj/eGl7tg4rgIES7j+LZsu8ZuDS\r\nH09vOCeZDcE4QaLMmUpNmBlDU1zpD9Vf8AQMODHzLKjloHmv9Ekmd7vdhgYa\r\nMIDXOw3BVq5vsovk9rWtUG68Hu75wm+KmTk=\r\n=UaQ5\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"737c46286670beddd53f226795f2b1e8e8c93356","scripts":{"lint":"standard","test":"standard && brittle test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"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"},"_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,"devDependencies":{"brittle":"^2.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.2.1_1658344075767_0.7706447376812067","host":"s3://npm-registry-packages"}},"6.2.2":{"name":"@hyperswarm/dht","version":"6.2.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.2.2","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"81254f1703bb9a6166c4d59a2a3a221a7362f508","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.2.2.tgz","fileCount":38,"integrity":"sha512-TNnxSIK4uMD+Jl7B5klXcioP9Jj992kCN9VJqVGkqrROeGxEQAGb6AVYOm731qu8b3NVk1Gfh6GIWmWJG2rvLg==","signatures":[{"sig":"MEUCIQC1YOhUioiAHJsMHPhfcnPk/fgEeBte/IsnRtyVm4FyaQIgOACb9mgXlBfahTiRm/bqZk7ZbnVCdoHUgXWoCQk+pnw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":147059,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjI6V2ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrW6A//WHfwwfc7lmMwl3l6rOOg24+PRnc5VyIIZgcmUyfkY9bqhxkc\r\n5kw5uzLVYWAACwGN+fJkX9jGXtIH/QVQ0MgYCKL9j/XpcxtcqU4A+DEZGfVd\r\n6KzO2h2wP5kEjBdn23lQxwVc2yWJKvWJVpzM0SdDZIOZ9/94vn6mCQMgwPwo\r\nT6O7ewqtfBXrrmPxFlDcAAt66Eb5wAE07dLpyM0gannm7j26aO9cM2IMKt3p\r\nHcyl53wwAXX9d8Smm5sN0sHahO3c8/1XRF8sreW+PULTvcO+BHuDVaO9lkvc\r\nUycOnP70MbGLwMqf2zP6aP4r+tB26zzZEyK4ANi0x24IPP4YJCLJXB1lQ/RW\r\nmRAA8JcvathZKm2MBZdxwCmZa6puU212pzmjUIS3Ml5bHnIaipffGjEivvL1\r\nP1q8UrPum+hgYacFAN0kbwt1ocat5IyjEZoYzftxz5Bs3v/MOM/A62MHIMMw\r\nIleWA9O/KB070Z44sHiUvGxbTYQZCBpwSOlwxev9HtGMigjNia3Z8POyo1cP\r\nlb1wsmEMVyN86che5B0KmJX3ZO2X1S414wTXQXNwu8XZZHZsghBpouCpTo98\r\nnOBytYzPhus9JYydnFw6LRTT9Z1Ll8Aocok9A78ALlxFxJnKwSW/l75M6vXT\r\n7MxElE/mu92cJSmj+VnciPJvhU/nDJjv4eg=\r\n=jc9E\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"37ab1920fb2c7bf3835274a6c99a6753a5396183","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.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,"devDependencies":{"brittle":"^3.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.2.2_1663280502708_0.483256255692432","host":"s3://npm-registry-packages"}},"6.2.3":{"name":"@hyperswarm/dht","version":"6.2.3","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.2.3","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"f9f3a77d931d7cd0ec2213d28f6e15abae3d827e","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.2.3.tgz","fileCount":24,"integrity":"sha512-p1+KhTkGwO8aoybSyIXC4vZatLgdDwTj516oQlPywT3cC++XCl+oX1hl3ROQcDoslTNwbKs/tHgKhC1sld1M3A==","signatures":[{"sig":"MEYCIQDUGRNCfqNlNE6Gzprm3QGh7Jma7gJZbd8mUrF/109LAwIhAMBRdLCOh5WUWp641dwT1EfJKTALLhcTvDVKuwHrxPdl","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108935,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjI76EACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqnOQ/+KdyvbGuwWczEf6oKAK/LJzonQ78Tu0cMtfARZBlgdioIEwlV\r\niG0mC5zgeJaTiYLNR77vkPtRU9ep2f6dZdvdjqFlVknVZ12hHyrTKMlr/+wp\r\n9r3A0bUhpLssWq/TmJsKCEVW/enD1/3mBHpGvNcnZ1o8C+UCMVEJpkx1jhwx\r\nIQb0d29aTStfU2JDJdAnoUlCcDHT/P1N77lJGynCEPXvccHaqGzgUfyMXE8D\r\nXO8I8nYi9SNLCqL0ia72M7832ZWGGCudrBzSZe8dBuPXHEZ2NQHrksRCDKH1\r\nXhrcuVNtHm3Z5meoDuJuBSHQXK3rHqu0PRsu5Icr20VG3VCY03NXVlUkD0px\r\n5DEJ0Q9OTHoOIUPqhAXq/a1i3roDrJ8boO7k7oqP2Wx5EMwgZfFrRhUXPDr3\r\nojNpKbu89/DofOLJYCEl5HOFZzYMCOLr7METlPgFDRDyIPDrfGAG5wuG20jB\r\n4m+MBXm0UOVjQVjh8nIEbWHkLtgn1o+ONpQw/VpqFV5KsbDG7M0cgvHUZ3St\r\nSg3+NL75KbIjMglNwwXWNnJnCXsCCQm2Ic95jFRFpK3QO3+gQH0BuVdW6UKR\r\nepPqdk544pZbmTOjgfF1S9dQf6JrrF3Ok6HZ0AGtumZoCPHQzBqaJt9WDa3t\r\nPD1xZpJYTZp1BvSR5df/DGylXXRUMAHZWtM=\r\n=4M+b\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"c47bef4dbe2bb71787ebdda1b2752a12a334c8ad","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.11.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.16.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.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,"devDependencies":{"brittle":"^3.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.2.3_1663286916707_0.8723389806480506","host":"s3://npm-registry-packages"}},"6.3.0":{"name":"@hyperswarm/dht","version":"6.3.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.3.0","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"6ca5220f9be630bc302372c07114be9b868b2a1f","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.3.0.tgz","fileCount":24,"integrity":"sha512-3gUSSV/iBLIzFZ8O7fiEM+ABB0rb9GH6o5HyabQIK39+0SGOkGPbnrcmqH9aq+GuLTgp3CnnHsXo775NFY/W0Q==","signatures":[{"sig":"MEUCIQChVy1bZfinsgD9ecHmv9mgiaA+igz1LpSQE/P6g/1slAIgJSjn9P8FgZ2YVWCyVvIsce7aKHgtWGOCmgSZ3IcPx8c=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108971,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjR+lwACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpJBw/+NhuyW7xAx9c9zOmr9P7EiItWyZrk6k7GSVHeenoNZmqUc+JF\r\na1Ggf5YKZ1UNJcGdTNzcFSP0FasxAyOoZ4nmQfFl84nAKW/FdivV6K7zsJqY\r\n3S1jqwmJut5xG06s83SsCoQetoTovSC8HuGgXOS5eK+g5d7Op10t6f2S7m0o\r\nK9Tqmc6YjnQmeHDBq8cdVIh4tudFm959C5SE78aX00ENdsB2VcehHJpT36sH\r\n8YqptBOWHRrz5TF8bcNXIdRY0BEkfbvjK/QFhrHY16yHeK91oBOkRgbXBQcG\r\nzEqRNQvAlpW4rCM4H9VoEa+Rh9sq0KtD7yU2k+FDBZu2fyPVBccu4ITQCUK6\r\n3ooZDzfN1rMWNEaXp+BYFUxaJRUOShk2bM/OLPJ4SDq23nYNHfQPnCiz/20T\r\nheytsEuHquxPkS9HpD6zfS2qtMNVGb5dkqrPR9DzIc+Epa+ZZrrxxGpiWdOl\r\nylvmUwdfR9IpAoBi/SCT+wr1VHAyFVGse3AwsDZCsmRhlJ07KnFJG2HjOyvD\r\n7ILvdupZe8RS7sd4BAKkdTHcHsztEI8yix8Pt09OAQ9lrjMtn5yPuzBgfFsR\r\nP9qOAtGDudFc9HMOCIlFXNcGgp4Rnwmrs2LsU3bfA7f3JKOTSsY+TAKhNQ+K\r\nNX1JtMw/4ADnj8ZJfHjjCOwDuIlGaOFp/bw=\r\n=Vh8/\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"51fde3e496ed0ba69743746cb3ca5506a6c6d887","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.0","udx-native":"^1.5.0","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.3.0_1665657199998_0.2311197347996452","host":"s3://npm-registry-packages"}},"6.3.1":{"name":"@hyperswarm/dht","version":"6.3.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.3.1","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"5fe40f53041d396380f21b545569fe2bef123933","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.3.1.tgz","fileCount":24,"integrity":"sha512-+lx+Tfrt5hb7Jf07ATS8M5b46skORaU6FIscu/mm7KGsLplljnARELtxEgdUTBD/QWJI/7TlA0B2mdGuK56mDw==","signatures":[{"sig":"MEUCIQCPV6xeJlmQMDg9IiMANNC2BRU2L5BA1as7H/0PSI+nrAIgX4sUYFEc9PSrnchndUGauxvUzjClG0Cl8kpSHegpK1Q=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108964,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjUqMaACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpvUw//XiYLZZ8pmz/PKPj+Iq+43FC75qFtB99rM0XmL/UE/OYbFzC/\r\nP4mPWUcYghW8CZhjZeyDVOzyFFRPHCXUGXNLQPML2yDc751JzBG9XKEs10fl\r\njaTuEzHhPKRTqMjgahQchgJuRld7o5OAFKpa//KiemkSDDi1caS69Osv16cI\r\nNIHGhJsvi2iv75E2zRWb49At3TWZfGbUwvEzbbjG2zOP8KHR1ycwyVRU6fC3\r\nRbWSwJxSVGlpsujVF2WCzQglixaZbRCD2Fk+1jCI8jaURmxMmk4QJg39/xC0\r\n/JTHdhCxGi9t9GQRFRDzlkbqduWhj83yk/i5XPYfmglKqnCD6Oi2X3lkk30l\r\nZAJ2+2dFHZoVQc7w3wOo8/eF9ubTmV70jY5RhTYuyEXhjIqGCpgIbWNwLkgT\r\nYdjBnxT2E//sz7NQZbhvF48m40y+JVcQeOG5BU6eu1TeW0uWsSShyU1bm2nF\r\nvGuBKCRh25pGuwvSo1ae39dxOfiUP/iy/aVO/47N0xzTQ4KIOMTbsJ9EetKN\r\nUSqXZpltXdz9WU0ctjzMLmqqL3uTUdEkR5CNHjp+u1N6AbQ3Tt8Evbt645gD\r\nzJMLMzOuswSjh0zW/FHXpuAirG3+Vk1cQRwjJZaQAI2j2A9ah8TH1iiOcuCP\r\nApHmBVpnfT0aNY16K0oHWKkLpCdadIg/lKI=\r\n=y6oA\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"4ac31acb448d5e97e6b77aec99b7d21a74c50a1f","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.0","udx-native":"^1.5.0","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.3.1_1666360089948_0.22037182717874115","host":"s3://npm-registry-packages"}},"6.3.2":{"name":"@hyperswarm/dht","version":"6.3.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.3.2","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"5637c0e88d9e56de11cf41718a30aabf4e58941c","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.3.2.tgz","fileCount":24,"integrity":"sha512-1wI0uJpl9hO7vzPVP/cIxxGAs3QeUhb96PuNPvc+I+GrEpCMWxd+oGMsmq3ClbzMXexlPkoFeILB9PnbVNnzxQ==","signatures":[{"sig":"MEUCIQCJuB/DyZvI5GeXrqT5PyfuCdXlI8lmXIxUD+4sZdUm+QIgYHPP2/l+kzm1AvTSay7t5XKjhvjGcNOa5tFw68zeXMw=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":108952,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjalQmACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrLDRAAizangjEtLf7BIbV5pBUuFClarfn/zV0NnL047TTWameppfiZ\r\nrko2lJ/O0+T5D5R8+UTW53O45VpOkQcqIvEV4IRHdNhrGjKyHyfJCxfXbTdD\r\nhFO+sRjetD7PjMBL/8ZYpdCSNVr5UYBFVP/DMAkaNLg1z7AFE8UfijZTYnz8\r\nJMVPW7wEr5Y6uj2FFPce/ml3mvzPHyO1F/DKhs5/sg618rG4uQyTED+vqHGS\r\n5IK4YxE+GMjy+FelRLq0hMt96F+oTkMO6xtacUKbUspTPI/oXZTkca+OCqmA\r\naIUygrFJuSeMPXOWJpPn0FGocMRaEt7IxHEnfCGoZEa66t2Fx87TUIsduRBg\r\nWxXnOF2gJ075Ljp5DOEL5FyLSVvOZeB15BP+e0i5BFH9AefzhkG1Dmhp8jpJ\r\n9GrXOBhOkatdX9AwzpPQ9VZRqbTJrzN/aUGhFlhy2echWgv15YW6wYx4AY3i\r\nkKdYeIbnfwd9vugTqHygGHhsS7qdjq1TF9IdVaLGfodpungeXyXf5AeJd4qM\r\n5OVrd1kIlUNfwSjiRG69lt5dGXCXhJCHZ2tqTlkeChnVv3mn0SSCHj+5vyg4\r\n16mau7f7NA1+LXmSJodBpvJJ8GaJC0jwiEwnISirTf3n0a3owRKOdQgL9aUr\r\nmJ/9eurArmQWVqLLb+AM9vQuODDWjPOhe+0=\r\n=iHX+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"90e509ea8426e45262cb022c33d0d99e8e0d6a61","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.0","udx-native":"^1.5.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.3.2_1667912742020_0.20829100142393497","host":"s3://npm-registry-packages"}},"6.3.3":{"name":"@hyperswarm/dht","version":"6.3.3","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.3.3","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"a9266cb56549f74e2d5dea587aad00c483799ad6","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.3.3.tgz","fileCount":24,"integrity":"sha512-2eGtS2i0Ij6zQL2IuDWzUbN6/c+NBpigBzRsH2/x2aA+8AJUO0IL3BaHECnO69T6WigCOMz+mp2exFkDjjGTRQ==","signatures":[{"sig":"MEQCIAq1KJ0gmqZhIbGrKte6p0gvgeQg5kHp2s9t/mtz6mwaAiB1rRa9OB8UowZW+RbzZq5j9FMZ2x5rRCKDL3VtI6BTpg==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109073,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjfPIkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqJZxAAnkn0HcRBTNgYPVPm0dVvSeR0X/mkYvaHObPLWuazlq29mLZh\r\noujTfC8Bdv5x1U4BwJKqzCCHHLKQmo2TLJtWS8sGSCJl5Iwvw1OkWvyfEqLf\r\n6D/vfCVWnVN1z40rqGuQXQB8tvbzLChG1LDXuo0uKdxKdOXrVkNb1VlyDf03\r\nCGHAvCTdz+dLD4ZSIchr6WXDRcAFxj3xooif/U4ay9ZiByYS4iLMoY2bbokj\r\n0EzOs9Jey8prD5Au3L7WwKrWpx8+7/PAdZCrDCdP/W8iezhhyaqYeRw400fJ\r\nx7q5+0EdB+XPQtAfM0YgtuqBWlGL8phqWEr+lpWcFvqkgDOFORQdv0PaywyE\r\nTaBsLfmqMAXpMKXuZ7MxPHALgWKYL8W+LlJFEY2coZr+Pferdc1uMt+c0HP4\r\nndzFnScx+EMIIgHJgr1tZ5iBcyti/pM/w+lyNVMT2IOoiug/hc26OYeyFvIb\r\ng3UOEORw9CPqAuAe2Pr8OKhQt9Sh3higaPFPet7pKiLjlkzZG554mY+C89LD\r\nf3ZZdlno9O7JEpodlKKSkn76fFb5x8Aqj1P5mWOQRB4yxv1oG25yzRyz2xVP\r\n6hrcnM64eE6MRKrUDT09A9EF5SH2Dn/1AAWPeJR7nQav5ZL1uIdtK40XWMZ3\r\nZni3AeOq4ro4qtHOHYhBDK96ljRiJgmymnQ=\r\n=RQnf\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"e2b4cb8588d1954765f176c2f092ecf72966f2d3","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.0","udx-native":"^1.5.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.3.3_1669132836413_0.6846537608055994","host":"s3://npm-registry-packages"}},"6.3.4":{"name":"@hyperswarm/dht","version":"6.3.4","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.3.4","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"f602ce276451c1653c56e06d92825476e3bab268","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.3.4.tgz","fileCount":24,"integrity":"sha512-dTYRP1LpRan1Ercx8RNMmhZcTU/Idc4TM8jv5F9LXOSnvBUc7RcHF4vb+XC6PsowRKXjqFiEtdTUN+4+HQd3rQ==","signatures":[{"sig":"MEQCIEGnV/mmLS6PWG7omJjjbYyPINceGaY0euWufDgKSSILAiAWl4GAiAf5QXgm3/gx/59zSjW6N7+Cem/9iZSQHj1zfw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109360,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjkgQLACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrU/g//XIN6ShyEwkG13kb5vBcz+ru7MuY7Zb2JHOEvuRTJHuuz2M2F\r\nEUl4CpTdEiyc3sGQnwafN8bFDl06e7Fv3GhzQGcDxoL8AvDLMS9jT+LjC+Ss\r\njHWYU0RAcIZW9Mh5u59+8UTpMRMxY1klh5B7e7M/TXqKj7qyAHE5D6irBQOI\r\n+Og92YopKg29PqWQCRiRKcivqRZev34fPjNLTtYbnGsfpQ2ZNgUCtdGcBVCF\r\nTA019yK+yXOu+ZuXj3bNrUMblC3pjqbOQ81pjqe0s9y+0zS4m/jHhjrcl2MR\r\nVQnFNK5GnsMRpm6Vmw4aesApRlZ6pAr8NkTi+jhFHagYBZHBcp1zWfZ2vBCu\r\nZBe4MFkZKwlBSvZNMyphxtarHwuOHzt1p81Lopu3xfuBntNLWJvlO2RvjiFy\r\nQuurhRFkk7O/riH5WmK/GME8LEmwm7059/9VpEPbJ/AUDN+o7Se+vH4gZGYr\r\nq34z7KQbDz/obY3Zef0eiylHW/YZJ0PW1YhV/r7rZy5C1a3xRJHX4kYfIPua\r\nrxeXmo4Ihn8Ic+te3pvCrf2bucnVfdPVaMnUkl4piVsCb0511opFoD0gTlRo\r\nUQKaU4Dk6wZBxfy6jdt3oRSVcJmamaU0fDLCxev+dqDtp4M86z9KRVzK08Zm\r\n6jP+5NlmlFeZ/Y0bC8E9E2tatT7vxNdxOFk=\r\n=sCUj\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"04942378259f2bd295f0ae0053c107ff45a1d93f","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.0","udx-native":"^1.5.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.3.4_1670513675555_0.9608798458672563","host":"s3://npm-registry-packages"}},"6.3.5":{"name":"@hyperswarm/dht","version":"6.3.5","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.3.5","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"a6987dd9815dce990d86de15a02ee8689c82e122","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.3.5.tgz","fileCount":24,"integrity":"sha512-e3sEtNdCHJ94lnfCaUgYt9jwFhMFY7OXkJvIE/ySt480uxkCMsSPSGwASPHxzClMA0KgOswI+kyE283eBtwx9w==","signatures":[{"sig":"MEQCIE1fGflVRhx1P0I2L/maZxxOy1sX3yncnrLGrJa77o4LAiAFBwVr/ebenOjVdbAhcKHszQhN7mqqUv/MKMGRIKaHRw==","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109916,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjmeAxACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoZYg/+I6WRhGiVzkKGoAw7dSBq6CEU9I5I5QuGb+RwC6eoAmEiM+Sd\r\nnXS++rfh7Ctxbwdd4mqB/HV4r9y6CnUZjhvQIg+gRxN/MY5sRq83BwZqzrEB\r\nCSvsTiP5qal1WEngA+WRQjFaumges97/mcQgBsXnCyHgZ2yCtek1MmzB05G2\r\nUxHtjrjRRGGlmuA5L4+kuCILa6Z18mTqRvXvJywzYotT2AGScnk1de6/WlXZ\r\ndZ4jz0W+otCpCqJjVcLWnzc9I/ATvueyqP4Twk7dSI1l2p9MC1DW9a+Q47iC\r\n/PWSx6rVnQbt8lystGfKyB3cdQUwDXrNBJVPQjNXh+lFA+ko4jpIn0rSDdUl\r\n9A03qwGFmPqNrLEXjDHzEUzdYNTrp9sH8lwj3da+cZUrHQsD/t8ckAjXvV4x\r\ns3TpUmnq9Yd0ROSjg+pCMbs017WYRFCyabFBSVGze1oEz2O1J44IaXDt0QPy\r\nr7ZnVZflWThYw9p2XzTEoh8M0LLWb7KBBbfUlNVK5KbBUEe7uGR1U3N/7kZL\r\nA84yvPHwlSVfTGpA+2tw0vqvMMCtTbWLwzTw0vrwGGiwkW8bkdHwc1VC/jPc\r\nLWmxEn9j/mX629onYRFWvWOH6obJidB3cjx6bqRByQYT5QBFcCz/lrhRtWJ0\r\npjG17Etki7CEUVjdbL+IEmP3DxiM2WMnYBw=\r\n=xRpe\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"1449d0d6aacc3f4ce1c5ef71eebbac5e62553efa","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.3.0","udx-native":"^1.5.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.3.5_1671028785349_0.4502103633258392","host":"s3://npm-registry-packages"}},"6.4.0":{"name":"@hyperswarm/dht","version":"6.4.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.4.0","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/hyperswarm/dht#readme","bugs":{"url":"https://github.com/hyperswarm/dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"c5698074c1c036455db8499e68dbc826da47e375","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.4.0.tgz","fileCount":24,"integrity":"sha512-LLIfirUPgSsELso3fx/32j2pyoc1XGXBwMSXJHogoU/1rpuILXjiP0JHQnXSpkBGVcT/mRew0bBcOyIzG/rzzQ==","signatures":[{"sig":"MEUCIQC/1FYo2Voz6X8l4oF/QsT7uvgAgOPPrAQkiXFtlfFygAIgdToPWDzjE3HXsxtJJDtK+d2TASgxKE+SBCMRAoQYU+0=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110412,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjo0YrACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrlgA/9ERyN5eD7RXDgQdPTl4rtV3Lkmi5Rj2Ybwsi72OBcPjshXd5v\r\n2d7GO+ashGqLfHoAC/Y7QAM+LXROXUIrH75zVFC7ELHoX6wc0eV79l1BKPou\r\nGacBxwavtEhFaTeNVxY/OolXHi0ykWRMZ6QAuz9U8alGD6jvYnE3zavaiwkt\r\nIw/yo8da1U7JPjcNoSGkzEgjN0L0f7goYLf1pCDuHDdwGg3svTKxG7ofmzsn\r\nWlbIIfVEKPIXJjVTQm+m/7SVkR3YOllWR10HGReF3lPRRQG5LfoGkkbicMql\r\nw4eC4PCiKpYLH488TKmt9E+DMLUVNP07dkUT24Qv3xUO+FMLLl7rUsHAEG6G\r\n0yyzgnRQ4idqDwhkqi4enqexydIwUsUumXnpgtP4LJG3ldpgz7ERVqrHjdkL\r\nK8DB1FzZ72LnCSWlL8v+zMsZHF6bgGRdaYul066k5peomUnGTdC/IcGancYj\r\n77lE7Wwb0VOaJXiww9JuwyAyyASWA6eD6grI7RQ5I6BCTxxxt7M29hvF0E1L\r\nQTK4wh31LJdKABJbYPht7fxJhRUdBJ71qzThis+aYudX4rnC1NadVKlDPspv\r\nJjg66jiiUx5j0k51dXaAaCbCjHiZPqDgcb7HXYKfbujgrRAzwckrFtAe1SMh\r\n5kCbWHoKYZHchqCdYnH6XcWuHuFDXc5d5Mg=\r\n=Gpb+\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"b9e101ad80119c734f9c6270a7db9e75fe68e93c","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/hyperswarm/dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.5.0","udx-native":"^1.5.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.4.0_1671644715796_0.9322663318316826","host":"s3://npm-registry-packages"}},"6.4.1":{"name":"@hyperswarm/dht","version":"6.4.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.4.1","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"6e07fadef317433c7cc064388c69fa0d1084df25","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.4.1.tgz","fileCount":24,"integrity":"sha512-BoBZlcB5RZZYdvWslAN+ciJvk0+Ayq2Se0X6GKM3C08xafRPrifJ1Vw56X0K3KijJUVGct961L5HcqtkuHc7jQ==","signatures":[{"sig":"MEYCIQDE5epugug98RG8PSq0wrOa0/WHR2APFGvNWaHgd6EA7gIhAN8ahqvA+J6uGpRbMTML99df53C6WLhE29+pZPLaMFnA","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109628,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjtJYkACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmo0WRAAlP8FN8VCJg+kX63g0xXZnoIyGx4dUsBGqgFlJwGBixKgkmuG\r\nujexkNm2NaMV4q3y5MpWSS2qY7m0tSkNU0j3s5qbEhyNmhs/WSmyc3Ldifd2\r\nDteDF2Hqdy5TyfchV+FAR9l8DDfAP1Q/iBtGVp2FZx9dbDAfV5EqSlvNezOj\r\nPYy6XBeXUanTJOUrmYUFfsku0+TOYAjr/SKiyVvgCIulro3QFyWKE3vA5nAU\r\nRQCVFG937GpgH+yPS1qxF9vUvEn29rqvuaPm7Hxacq9L/ZhRR6vOD94sYfbP\r\nj7BDZom0/iLLUPZkQ1KYDOTb2p49O6WwTW6zuEy9M/7bvglzWOKqov4yVXKD\r\nXbjQq27KE+kjKKVYNX8yhp58EiTvjIHv1Z4DHRYWFSDtaqeDcmoSmJRV6eKl\r\nQlwVito7Y/Eez4Aak46oODTs6uLeEGHy2n8J7C+EDJOTarDXacXoyUth4nqk\r\neFKt6atG2YwCFepWa56MBsZRAXxyHUUofrLpvtpvQozoC+8QXIQbRqbzdPyR\r\nVNWgnWrm3BroIlMrS5gQ/gJ8ZvSH5Vr+qO5SassKjTgL/Be44hVLPhpeiNt5\r\nm4dJHM/I/4QrAp/f6Zlsbs6keCEdtuuqmvjhY9p9qkYsUj2oWApsOZno+vBL\r\niOLBJBWwsIapoBXorz+OMe3ZxXfykoKlmhA=\r\n=v0RU\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"559b87eb43d874a6e9ce5bdee53712060cbcbff8","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.6.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.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,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.4.1_1672779300452_0.7019529472534305","host":"s3://npm-registry-packages"}},"6.4.2":{"name":"@hyperswarm/dht","version":"6.4.2","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.4.2","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"2be8a764ad91ae7769076d6db61d25d82578a4b5","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.4.2.tgz","fileCount":24,"integrity":"sha512-4DEzqtJuxSgXTDIB1E3GrO3/kS5a3uOmlLYcCtFCeDHO1gqAR1eI7YBA9hy3gMt8zFwkQ8Q0UnjbhpOBv5qcMA==","signatures":[{"sig":"MEUCIQC+7sNFrErxfeM8AvsvyblQlKPjMI6xwxZbtMkw51VDrgIgTpPG7NkY+gGqJwkFcvaDXbpQBGvhp2AQs57eC00kg1I=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":109628,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjvT7nACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqCnA//ZwAWIA6W4Yi30eMhiIyvhC6PmIkMETG4b4vGyc4KW9tF0beK\r\nzSFbPFh6BNngsNrmA1qgCtXopmER4WnabusA/n5+PMUAqg8zHenmiaieBTxa\r\nU/xr+307BDJXjp+w/TetfjUJ28JahQTDrK4UmjwWoLYnLPHjIItHpxBix4Et\r\nV+3uyaaxPU4SI5r4uJHjY3POOH/2atmBKRVkKzdgwlgcI5geDDYMA9ePKmCn\r\negNBoZXFDFNvoQ7Tba2yurEzuSQZYn0r83cQFTSiqD43l7Qngw0jYFEy8Pti\r\nOkmK6JjsR6aywDJRwIFiCxNci3YG0Rv/8dedopZTQ20qnGi+PGa+okbn0HVl\r\nX/cIS3s1AT3O/iTcfQOsblocFzbKXVQ7NZBruFS5xYd4Jy+F4PfLpdMdR+5a\r\n3rFhG0NvopFUqFoYsAKMdeZ1NYDfmsP453cIObx5xt/FoZJJX8P8FYKMhi+T\r\np/GBTibj3Ed/OZBaE3Z1d7680XPkimYnqK4Wh4S/JAdEcA9NXnDAns3AtYIO\r\nmlkmkHLqsfZRl1jQAuo4QZSW+Jisc/hBnPJiP5tKkXWCWaVMH0p4IT3nbHUY\r\njvB6jBgyecIkKLtG252fOKUaAuKwUWwoPMuUB662UK0bTfAfgYU/4a2alRcm\r\nB9VcRdgFdhWmnHT+7qGSYouBRRtP8fBrYZI=\r\n=FOW4\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"077d6ba7301b94fea70bebcba7e9e9bc06bb9c29","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.6.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.0","compact-encoding":"^2.4.1","debugging-stream":"^2.0.0","hypercore-crypto":"^3.3.0","sodium-universal":"^4.0.0","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.4.2_1673346790836_0.5199838293360795","host":"s3://npm-registry-packages"}},"6.4.3":{"name":"@hyperswarm/dht","version":"6.4.3","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.4.3","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"f8e0895b59e1d6edb77fa123e3ccd674b7ff51f8","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.4.3.tgz","fileCount":24,"integrity":"sha512-sxzlVNLUHZV62dOZSPEaN5I2pwgwcwtcbVas+G6bE+tnEAdRf9qjNjGSgbTNk0ZqfX8Ai64W567zXH9vtTB4XQ==","signatures":[{"sig":"MEUCIQCjRpWfthqc30gKhu60ml0vui4LQybJmQs/RslUOz/7EQIgKPxNg8gi0WDUCQnulXxLPPxDod7Xzgk6+m+xiWR4f/s=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110287,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjwnmNACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpfwg/+I3YuTyTvWVTqK2R6pnK0eOuMosBTxmODC5xB3wlHA/FBDHIQ\r\nGzQfCeNwYK4sCBdIJnwXLbIN4sB0q70rDdJodNTWCUh8ypWEkX8VFRiXT8Iv\r\n98D/Vtajkqe9xKh0c/6t8OKR8OPvpAD4axiNw0HC/B2zm3Cb4AI1KN+KDDqe\r\n7oJcYWKZxN0E38Uy2ubF7RYx+Vk/yA9ihqqW60SrxGrPOVQ4UQHvf6dFw7F3\r\ntkzTNS+U0GCK1Yjbnlk1/WNS482Zyh8W3cdALJ2i0KPZNC5nRgEwJnXlJr3K\r\n7qLemKqPkSq02cAMPr6SzGFl09zv9mc50M1jWnJKyLD7iTqb8aabFsvTC0EP\r\n9eURnRgCvkl18Jp1Dtlai8H3ce7bv3Y1iUCJNfx2+zAVZ0GY6PgVwLHLhkRI\r\n6aUcCa0crcrn750ZMGIDyk20m8HCR0/5aznUg5k9F9YTLkLWPv6CfujHkt2k\r\nrafIZEIbU9yAlsI5m9OxRDr36Ig8pV4/efVwGJQwRj7bun2a+QCGa/IySasX\r\nQmWaGKUdz33hEDLgLLMdCMV/96yCqLiIJxE41QlYA4341O3mhTaticRWFyss\r\nNL2eD4foqJ8FBc6M/5pcF1M3aG6GIPIJrQJfdiJYXp10QOTC8FUMYnRqxCtJ\r\nTXHsO7azW3WWFud5/AYLfuE2XogH3ynoQh8=\r\n=0nDZ\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"c95cb547036d84649de730d6a26248cb102e59cf","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.6.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.0","compact-encoding":"^2.4.1","debugging-stream":"^2.0.0","hypercore-crypto":"^3.3.0","sodium-universal":"^4.0.0","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.4.3_1673689485069_0.09427772949001767","host":"s3://npm-registry-packages"}},"6.4.4":{"name":"@hyperswarm/dht","version":"6.4.4","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.4.4","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"aee0e431ede7fe81311342db553775dccd816a3b","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.4.4.tgz","fileCount":24,"integrity":"sha512-yqOZ4iaOS9MYIMdC03lZ8scam+ptspTwL0rMFJILF+LU3LT8QjUCRHRUbUOaZFjZ0tf0g7+DICRILMTRwSQ/Ug==","signatures":[{"sig":"MEUCIETtG4UWxYZo6MA+DMKTXLEECwyw4nw1LHUsi3ULy111AiEAz8tlcwc7fAWwjStkRvO0rJIrCaqOWyaIPCv2w7g0VNo=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":110288,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJjx861ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2Vmpc2RAAiQPm+1LvxeFjUT9b1FxOB+EZ88PCu4giIqUCFgBmWuaUnVuu\r\nrU7fyirbLoXMFPlkseVBfoe6Ks3K8d46N1SQrcICXq5g/Vcc07uSKqoCfnNe\r\nDmyOeRIkkBhvU6hWXrp6sS47YCboz2hcDd4PllHU4sqGoNAMPidly2ZL7UxI\r\nVOn4wtaMEwHH+jLKu+3Xbv7J6oJ0X5B4uE8daZt+qsoIncewGxUa72xd8E3Z\r\nBYbp+wyEGVqXLlShqmZ176oRNajCiIa8sRt7bOa9fuhLcZ7m9CnfrXUTA9pz\r\nfs4nEjIt4hV46Sj9TapEiQ1P3eoxsMrt+3fbQgCjywPYFCj/waPbTUQlCwn+\r\nwpOPWu7rMpPlxosH65+UAOIjGmbVCQPjQE9rssSbt91EnAIh8t9AYJhCygAn\r\njN/c8x6I3w9Xn2XvMTNxlLBl+IVBUVplrd4MSLoUYn4ID5BifIHsQWPlr7aP\r\nuoi8rPXnPWiqi+cprDwEqzFMXp0ZmE4CBt51XUB5vqxY5nDZPRTqEfMF1fh3\r\nwPfDdI/NOAZxj7QlsBl8lqin9YR6Z1WLBGDf4dVFxiGZmR+DD8KgcigEt7w9\r\nAwuZFPa7zCaM/W1tQkQ+qR4hToeWN7oHKnzlvNxxZY6BZQuhtGLLDDnSsEs2\r\nUt96a8nJ+oCfQyX3NblZvWQTjhVCKaa7cCY=\r\n=G/LL\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"aeee9ab0ef2a4863db6da8ec72eef9863c84d81b","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.6.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.0","compact-encoding":"^2.4.1","debugging-stream":"^2.0.0","hypercore-crypto":"^3.3.0","sodium-universal":"^4.0.0","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.4.4_1674038965468_0.8100922610335082","host":"s3://npm-registry-packages"}},"6.5.0":{"name":"@hyperswarm/dht","version":"6.5.0","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.5.0","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"f0d392f7e05c0ae4f28cf7d4c178205889dddd49","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.5.0.tgz","fileCount":24,"integrity":"sha512-GehqKOueSJY0Jbv9UNdCw2PhQBnRYmlafINk8O7Xif6JEtHzA66mg09G5d6L7duoy+I57CNLUSyv5JTQ+NOkXQ==","signatures":[{"sig":"MEYCIQDVXuyuDipegNqyAmT81l0/t1WlrAS/Yr/xSDuL5IylOgIhAKjxDaxV4FY83A7rpYY/S/KxBaf5L0BdfyOOIm55EE5L","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112612,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJj4nSQACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqpTg//Tc8rO8nw4CEiNKcBmWrs0qrnVi1pFTX+QM1UUGZt3oJ9kT1a\r\njkIv/wXm4QopFvexoC+H73HqCTLjRu0/git/H2RXx14dJESmbBoNrlAYdAQ6\r\nB8BszR1Tb31JCawtv4KC80wllc9mckS8bRRX7ALLjwQm1r5JLawFKrSj5Qsb\r\nxxp2I0j0gwHrjNtr2nddZ2jHpIW7b09Myq/4Zw12oVhjqvsRshFuBHH6R4Cz\r\n+P189D1wyTpd49O0lup9n46EO1qgfXMwpaEo5VAXufQZ37ahjspKYPhLGNTP\r\n+28fLdL50rewVZrbhBlQHp0Jo4f3Mjmn6ntGC4PvuSIlKg5i7HXuvPEGcrW6\r\nsGlN90lXXkBiLRESMOIXgu61mqmz4Mtb0ZfzXcu2BBvhFDntNzg/YAkPpvRH\r\nno8vVa1k1R+WnNL/tVjYAC+o6wnlhEtiy9rLwGX6ywApURUdf6jKaYJB9a8r\r\nooxAiNg/BolmfBPQxgiZjYUIykAvFt2kL/Qsa99+OiqQId0UKX2C4sruE80T\r\n3ANvp1IAV1h0bnNncdxrl4rsA3BxdU11K/+GqAvi8lZi3Ii6CghlIltXifPP\r\npvhwnTL7rmSg7RLqrO8lQNUYWouwEibk25Cit/SgNk8vABilC+7K+iWe5o53\r\nBtjed8InlEu38Dt7Ejk3PrZ9AUDfoIj/DB4=\r\n=WS55\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"40653a29f5901fe3668a4893959a1b89490dd2f7","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.6.1","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.0","compact-encoding":"^2.4.1","debugging-stream":"^2.0.0","hypercore-crypto":"^3.3.0","sodium-universal":"^4.0.0","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.5.0_1675785360374_0.4284160836591473","host":"s3://npm-registry-packages"}},"6.5.1":{"name":"@hyperswarm/dht","version":"6.5.1","keywords":[],"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","_id":"@hyperswarm/dht@6.5.1","maintainers":[{"name":"kasperisager","email":"kasperisager@hey.com"},{"name":"mafintosh","email":"mathiasbuus@gmail.com"},{"name":"davidmarkclements","email":"david.mark.clements@gmail.com"}],"homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"bin":{"hyperswarm-dht":"bin.js"},"dist":{"shasum":"07e144590f532c2f872e3617117d17f266b2f7a4","tarball":"https://registry.npmjs.org/@hyperswarm/dht/-/dht-6.5.1.tgz","fileCount":24,"integrity":"sha512-TTTOzuwqbmXNwl+b2FXeHCoR2QS1sqxQvqXwv2i54sdEkKmF8f8t4U8PsRGk5PUO3qA6GxlMThvXixg9Fgs4Yw==","signatures":[{"sig":"MEUCIFqX1CqGFlqPyuSHVkyRdslDM7SM1XR4u6lYo9jeudu+AiEA3dzKck6uSxGO8Tu9FzKbzG0BxG72sglBy+YdO3/g2Ss=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":112683,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJkDZr5ACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmpmwQ//WrVlAnukO3YQstITtKNeyNSUTNLAaSRc+fSp6E716DQ1ls22\r\nfQqL/FJH3goOTD5qO13xqK8E2mzPkUcy32vdL7fiBBVaHlrJy/1JjesgOHNn\r\nD2CnfrVlBYcBnuL7akuQCrUsRVaPzuk5AyM8QkDEXCQOMsd1gTBg48za1OAT\r\nrK7m6ZQFh4BNp7tGxfLf0biFpg0ctsRcbF/EWjo9V7nnaeKEDZALlASE3D/X\r\nGopG7DaD5BkB0/09rcRGKpl5CJI+dXB7ED4MW6KyOegTpDvUYHapTs1USlc6\r\n2OYntdKpI/rCpn9fQA/vTJqro5u2t4FycrQXkN/TqAhkfcU4ZLG2UmrYW/Ev\r\n4dpvZnRxhgC2wiI9kRL8aH4qJ9AyZ95tgMPxrztTMmz38SnitYzSwnpZfyFS\r\nFZtHat679+TJ+Vb71eNsLeYOA1GCE0vf1sPowybNQsjW77zrdW09Nmx95MJg\r\nEBDzInvX4P2HKqpBZ37OSjE3xoLtfvymbGszLGhgIqKZbNjmCAMSkA9BvrtP\r\nvsa2aA4BBMBmEwV6JDCO4/IG2FU8/2MecxZOIY+f1Gi3KbjbqiByqfWoBPvz\r\niK5OUpNVWLuYNfSQUE6E+dAGyw+FaLynZjPMCMyYSa0VUfiCASFfvt3Geg6x\r\nDiLs/HIc8Th8rwjZCrBqz4CabVc5RQvQgHs=\r\n=xNcV\r\n-----END PGP SIGNATURE-----\r\n"},"main":"index.js","browser":"browser.js","gitHead":"3bec11a82131079f66e8afaf417d8c4b4ced4412","scripts":{"lint":"standard","test":"standard && node test/all.js","test:generate":"brittle -r test/all.js test/*.js"},"_npmUser":{"name":"mafintosh","email":"mathiasbuus@gmail.com"},"standard":{"ignore":["**/*.mjs"]},"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"_npmVersion":"8.15.0","description":"The DHT powering Hyperswarm","directories":{"lib":"lib","test":"test"},"_nodeVersion":"16.17.0","dependencies":{"b4a":"^1.3.1","bogon":"^1.0.0","xache":"^1.1.0","events":"^3.3.0","dht-rpc":"^6.6.3","record-cache":"^1.1.1","safety-catch":"^1.0.1","noise-curve-ed":"^2.0.0","noise-handshake":"^3.0.0","compact-encoding":"^2.4.1","debugging-stream":"^2.0.0","hypercore-crypto":"^3.3.0","sodium-universal":"^4.0.0","compact-encoding-net":"^1.0.1","@hyperswarm/secret-stream":"^6.0.0"},"_hasShrinkwrap":false,"devDependencies":{"brittle":"^3.0.0","keypear":"^1.1.1","standard":"^16.0.4"},"_npmOperationalInternal":{"tmp":"tmp/dht_6.5.1_1678613241719_0.5827685458500831","host":"s3://npm-registry-packages"}}},"time":{"created":"2018-09-25T18:47:58.707Z","modified":"2026-03-31T19:45:58.112Z","0.0.0":"2018-09-25T18:47:59.028Z","0.0.1":"2018-09-25T18:57:03.702Z","0.1.0":"2019-07-05T15:01:27.837Z","0.2.0":"2019-07-15T14:02:15.213Z","0.2.1":"2019-07-15T14:13:58.238Z","1.0.0":"2019-08-07T08:13:35.319Z","1.0.1":"2019-08-08T19:35:37.828Z","1.1.0-rc1":"2019-08-13T17:11:20.017Z","1.1.0-rc2":"2019-08-13T23:21:34.999Z","2.0.0":"2019-08-14T18:08:42.161Z","2.1.0":"2019-08-14T18:38:13.591Z","3.0.0":"2019-08-29T13:29:06.212Z","3.0.1":"2019-10-17T21:52:00.791Z","3.1.0":"2019-11-29T21:00:05.261Z","3.1.1":"2019-12-04T09:09:39.721Z","3.1.2":"2020-01-15T10:24:58.657Z","3.2.0":"2020-02-18T15:16:13.268Z","3.3.0":"2020-02-28T14:20:25.112Z","3.4.0":"2020-02-28T15:18:40.481Z","3.5.0":"2020-04-02T19:35:42.191Z","3.5.1":"2020-04-02T20:00:48.172Z","3.5.2":"2020-04-02T21:32:14.370Z","3.6.0":"2020-04-18T13:17:29.164Z","3.6.1":"2020-04-18T13:19:56.562Z","3.6.2":"2020-04-18T17:53:07.607Z","3.6.3":"2020-04-22T19:17:53.804Z","3.6.4":"2020-05-13T19:28:31.173Z","3.6.5":"2020-05-13T20:38:27.056Z","4.0.0":"2020-07-09T15:51:14.103Z","4.0.1":"2020-07-13T13:54:30.026Z","5.0.0-beta2":"2021-06-01T17:19:10.274Z","5.0.0-beta3":"2021-06-02T16:19:57.130Z","5.0.0-beta4":"2021-06-07T15:42:13.749Z","5.0.0-beta5":"2021-06-11T14:50:56.689Z","5.0.0-beta6":"2021-06-14T16:33:29.042Z","5.0.0-rc.0":"2021-06-17T10:28:50.598Z","5.0.0-rc.1":"2021-06-18T12:27:43.201Z","5.0.0-rc.2":"2021-06-22T09:48:06.966Z","5.0.0-rc.3":"2021-07-07T07:52:27.410Z","5.0.0-rc.4":"2021-07-19T15:02:54.678Z","5.0.0-rc.5":"2021-07-19T20:35:50.216Z","5.0.0-rc.6":"2021-08-31T10:48:14.517Z","5.0.0-rc.7":"2021-10-14T19:08:17.755Z","5.0.0-rc.8":"2021-10-14T19:38:38.823Z","5.0.0-rc.9":"2021-10-14T20:43:18.937Z","5.0.0-rc.10":"2021-10-15T08:52:31.153Z","5.0.0-rc.11":"2021-10-15T11:47:07.410Z","5.0.0-rc.12":"2021-10-16T12:34:39.263Z","5.0.0-rc.13":"2021-10-19T19:53:09.493Z","5.0.0":"2021-10-21T09:24:06.154Z","5.0.1":"2021-10-21T11:38:07.043Z","5.0.2":"2021-10-26T12:02:07.580Z","5.0.3":"2021-10-28T12:05:46.565Z","5.0.4":"2021-10-28T12:10:57.832Z","5.0.5":"2021-10-29T07:02:04.884Z","5.0.6":"2021-11-06T13:46:00.776Z","5.0.7":"2021-11-07T18:26:08.941Z","5.0.8":"2021-11-22T14:35:12.616Z","5.0.9":"2021-12-01T20:03:24.591Z","5.0.10":"2021-12-01T20:09:50.637Z","5.0.11":"2021-12-02T18:38:26.511Z","5.0.12":"2021-12-20T12:31:18.070Z","5.0.13":"2022-02-01T11:01:25.232Z","5.0.14":"2022-02-02T08:34:12.211Z","5.0.15":"2022-02-02T10:29:39.802Z","5.0.16":"2022-02-09T21:07:55.714Z","5.0.17":"2022-03-03T21:41:42.618Z","5.0.18":"2022-04-04T19:52:21.312Z","5.0.19":"2022-04-04T20:05:24.590Z","5.0.20":"2022-04-05T09:06:20.325Z","5.0.21":"2022-04-05T14:13:40.905Z","5.0.22":"2022-04-05T15:01:13.728Z","5.0.23":"2022-04-05T15:14:08.430Z","5.0.24":"2022-04-07T13:07:42.067Z","5.0.25":"2022-04-29T09:51:47.489Z","6.0.0":"2022-06-18T12:25:48.453Z","6.0.1":"2022-06-18T17:23:27.720Z","6.0.2":"2022-06-29T17:55:39.066Z","6.1.0":"2022-07-05T09:23:08.067Z","6.1.1":"2022-07-05T11:43:55.971Z","6.1.2":"2022-07-05T18:52:00.671Z","6.2.0":"2022-07-05T21:18:54.280Z","6.2.1":"2022-07-20T19:07:55.921Z","6.2.2":"2022-09-15T22:21:42.946Z","6.2.3":"2022-09-16T00:08:36.908Z","6.3.0":"2022-10-13T10:33:20.200Z","6.3.1":"2022-10-21T13:48:10.125Z","6.3.2":"2022-11-08T13:05:42.157Z","6.3.3":"2022-11-22T16:00:36.635Z","6.3.4":"2022-12-08T15:34:35.703Z","6.3.5":"2022-12-14T14:39:45.669Z","6.4.0":"2022-12-21T17:45:15.949Z","6.4.1":"2023-01-03T20:55:00.558Z","6.4.2":"2023-01-10T10:33:11.004Z","6.4.3":"2023-01-14T09:44:45.264Z","6.4.4":"2023-01-18T10:49:25.688Z","6.5.0":"2023-02-07T15:56:00.514Z","6.5.1":"2023-03-12T09:27:21.926Z"},"bugs":{"url":"https://github.com/holepunchto/hyperswarm-dht/issues"},"author":{"url":"@mafintosh","name":"Mathias Buus"},"license":"MIT","homepage":"https://github.com/holepunchto/hyperswarm-dht#readme","keywords":[],"repository":{"url":"git+https://github.com/holepunchto/hyperswarm-dht.git","type":"git"},"description":"The DHT powering Hyperswarm","maintainers":[{"email":"mathiasbuus@gmail.com","name":"mafintosh"}],"readme":"# @hyperswarm/dht\n\n### [See the full API docs at docs.holepunch.to](https://docs.holepunch.to/building-blocks/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 (socket) {\n  // socket is E2E encrypted between you and the other peer\n  console.log('Remote public key', socket.remotePublicKey)\n\n  // pipe it somewhere like any duplex stream\n  process.stdin.pipe(socket).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 socket = anotherNode.connect(publicKey)\n\nsocket.on('open', function () {\n  // socket fully open with the other peer\n})\n\n// pipe it somewhere like any duplex stream\nprocess.stdin.pipe(socket).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 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.\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, host, [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', socket)`\n\nEmitted when a new encrypted connection has passed the firewall check.\n\n`socket` is a [NoiseSecretStream](https://github.com/holepunchto/hyperswarm-secret-stream) instance.\n\nYou 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).\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 socket = 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#### `socket.on('open')`\n\nEmitted when the encrypted connection has been fully established with the server.\n\n#### `socket.remotePublicKey`\n\nThe public key of the remote peer.\n\n#### `socket.publicKey`\n\nThe public key of the local socket.\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","readmeFilename":"README.md"}