{"_id":"@bsv/teranode-listener","_rev":"12-4f78a6f8b5ccf51eb0e3e649f7928bf5","name":"@bsv/teranode-listener","dist-tags":{"latest":"1.1.6"},"versions":{"1.0.0":{"name":"@bsv/teranode-listener","version":"1.0.0","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.0.0","maintainers":[{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"dist":{"shasum":"ec3621c74417ebc1c8c037cdafdcc821bbba70fd","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.0.0.tgz","fileCount":16,"integrity":"sha512-flUbAz9QOwDVeRbcONMBm7WYSyWOnY7gTqzgaWqmP/EGpFq2YcExkT00tDjW06X4qMPQg1YtUpdebD9pT637Gg==","signatures":[{"sig":"MEUCIQDqfOveCLhbM7ywk4UA4H+WcwofXIiFNjvwdFgDNb/2PAIgHHpKq1cvfUrIr39lTde/gUOK7N2J776IvLUL2BSjdaY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":61748},"main":"dist/index.js","types":"dist/index.d.ts","gitHead":"a5bec280a0591216b0f05c4bfab5f16ac4ba3319","scripts":{"build":"tsc"},"_npmUser":{"name":"dkellen","email":"darrkellen@gmail.com"},"_npmVersion":"10.8.2","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"20.19.4","dependencies":{"libp2p":"^2.9.0","@libp2p/tcp":"^10.1.18","@libp2p/ping":"^2.0.12","@libp2p/pnet":"^2.0.42","@libp2p/crypto":"^5.1.7","@libp2p/kad-dht":"^15.1.10","@libp2p/peer-id":"^5.0.3","@libp2p/identify":"^3.0.11","@libp2p/bootstrap":"^11.0.46","@chainsafe/libp2p-noise":"^16.1.4","@chainsafe/libp2p-yamux":"^7.0.4","@multiformats/multiaddr":"^12.3.0","@chainsafe/libp2p-gossipsub":"^14.1.1","@libp2p/pubsub-peer-discovery":"^11.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.4","@types/node":"^22.5.0"},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.0.0_1753577620036_0.5434367413671519","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@bsv/teranode-listener","version":"1.0.1","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.0.1","maintainers":[{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-p2p/issues"},"dist":{"shasum":"55d8561a18664dc5e886b1c93e89134800d14f3b","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.0.1.tgz","fileCount":4,"integrity":"sha512-9HyybYBBSB16qF53vfJJmC21SDKWSh8bb4lxGnNKVaaWu2dCWwo9YIl9joXENgLMxc++lDDZxWTxpcZ9MkXZ3w==","signatures":[{"sig":"MEUCID3wvAnDr32TdYFtbn/VChu8d1LcHUCWA5hKnvPy5HZQAiEA1pL29sXj8pSl1P8O9Bg6ZOVmTXTUwldtGudUpAKPka0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34112},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"gitHead":"c1014293230cfd436aef4d7265aa0dc24d740790","scripts":{"build":"tsc"},"_npmUser":{"name":"dkellen","email":"darrkellen@gmail.com"},"repository":{"url":"git+https://github.com/bsv-blockchain/ts-p2p.git","type":"git"},"_npmVersion":"10.8.2","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"20.19.4","dependencies":{"libp2p":"^2.9.0","@libp2p/tcp":"^10.1.18","@libp2p/ping":"^2.0.12","@libp2p/pnet":"^2.0.42","@libp2p/crypto":"^5.1.7","@libp2p/kad-dht":"^15.1.10","@libp2p/peer-id":"^5.0.3","@libp2p/identify":"^3.0.11","@libp2p/bootstrap":"^11.0.46","@chainsafe/libp2p-noise":"^16.1.4","@chainsafe/libp2p-yamux":"^7.0.4","@multiformats/multiaddr":"^12.3.0","@chainsafe/libp2p-gossipsub":"^14.1.1","@libp2p/pubsub-peer-discovery":"^11.0.0"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.5.4","@types/node":"^22.5.0"},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.0.1_1753578638344_0.9640868555850912","host":"s3://npm-registry-packages-npm-production"}},"1.0.3":{"name":"@bsv/teranode-listener","version":"1.0.3","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.0.3","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"73c4a262142464486722796d379fb1c6da099cdd","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.0.3.tgz","fileCount":8,"integrity":"sha512-6BmB5mFNDJziaWQnqbSmp/3BRBEq4qbsKmBUWSCLr2YXqNety6vyMx5frH7GITxTp3hVXmfscUpoIxyJA/C3/w==","signatures":[{"sig":"MEYCIQCdHHCp61wO+JvXc7GcMrMsnb0zs66tdwMsYuEqCLvDdgIhAOkx7YJM8g11N3QDtj/7GjDGpAvOK2OhGU8+vNjOMfV1","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.0.3","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":50525},"main":"dist/index.js","type":"module","_from":"file:bsv-teranode-listener-1.0.3.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"demo":"tsx demo.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/tmp/9e53b0a54d7200932f822cff6bede740/bsv-teranode-listener-1.0.3.tgz","_integrity":"sha512-6BmB5mFNDJziaWQnqbSmp/3BRBEq4qbsKmBUWSCLr2YXqNety6vyMx5frH7GITxTp3hVXmfscUpoIxyJA/C3/w==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.12.1","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"24.15.0","dependencies":{"libp2p":"^2.9.0","@bsv/sdk":"^2.1.0","@libp2p/tcp":"^10.1.18","@libp2p/ping":"^2.0.12","@libp2p/pnet":"^2.0.42","@libp2p/crypto":"^5.1.7","@libp2p/kad-dht":"^15.1.10","@libp2p/peer-id":"^5.0.3","@libp2p/identify":"^3.0.11","@libp2p/bootstrap":"^11.0.46","@libp2p/interface":"^3.2.2","@chainsafe/libp2p-noise":"^16.1.4","@chainsafe/libp2p-yamux":"^7.0.4","@multiformats/multiaddr":"^12.3.0","@chainsafe/libp2p-gossipsub":"^14.1.1","@libp2p/pubsub-peer-discovery":"^11.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.5.4","@types/node":"^22.5.0"},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.0.3_1779136943128_0.12396701472968696","host":"s3://npm-registry-packages-npm-production"}},"1.0.4":{"name":"@bsv/teranode-listener","version":"1.0.4","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.0.4","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"a0bd50a9b084ef900bd3b7530d2b0c760b7b0ce2","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.0.4.tgz","fileCount":8,"integrity":"sha512-hPhJ7EV2iTJgUSi2CLhmWhiqXOWL8s+wARmpEdwcFDt/4tjyodf31Nj+FbWyQcX8CdXngGokX0sS8lN89Zs90Q==","signatures":[{"sig":"MEQCIEn+WTfMDhygl22ltp5nmKJdJUeokQKkD/4oZkl5BLVvAiA8BW0VYlDy4EuTt8fJ7a3xael/BGEDmGW+pvk0T7OS3Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.0.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":50525},"main":"dist/index.js","type":"module","_from":"file:bsv-teranode-listener-1.0.4.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"demo":"tsx demo.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/tmp/570b5544e7f0f113b8d17f03bb378486/bsv-teranode-listener-1.0.4.tgz","_integrity":"sha512-hPhJ7EV2iTJgUSi2CLhmWhiqXOWL8s+wARmpEdwcFDt/4tjyodf31Nj+FbWyQcX8CdXngGokX0sS8lN89Zs90Q==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.12.1","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"24.15.0","dependencies":{"libp2p":"^2.9.0","@bsv/sdk":"^2.1.2","@libp2p/tcp":"^10.1.18","@libp2p/ping":"^2.0.12","@libp2p/pnet":"^2.0.42","@libp2p/crypto":"^5.1.7","@libp2p/kad-dht":"^15.1.10","@libp2p/peer-id":"^5.0.3","@libp2p/identify":"^3.0.11","@libp2p/bootstrap":"^11.0.46","@libp2p/interface":"^3.2.2","@chainsafe/libp2p-noise":"^16.1.4","@chainsafe/libp2p-yamux":"^7.0.4","@multiformats/multiaddr":"^12.3.0","@chainsafe/libp2p-gossipsub":"^14.1.1","@libp2p/pubsub-peer-discovery":"^11.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.21.0","typescript":"^5.5.4","@types/node":"^22.5.0"},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.0.4_1779597558044_0.08024339740011088","host":"s3://npm-registry-packages-npm-production"}},"1.0.5":{"name":"@bsv/teranode-listener","version":"1.0.5","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.0.5","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"c0387fe2b806c10118488b3f9d900c2b142dd58a","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.0.5.tgz","fileCount":8,"integrity":"sha512-D7wmE1AK+hd4cXikZfFm/JGWMOntlS3rmCEnUshKlt+pVil0adal8sbv3nraMFhdpEAKqiVugB92xiq61YvJeg==","signatures":[{"sig":"MEUCIB8hVGdleibnX51UqZCqo4fNNX2Bv8TxXFf1+n/ZAYAEAiEA217ZUI68uawi0g7BL2nuVZbUdqNCV+8U4n+nprQj6G8=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.0.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":51198},"main":"dist/index.js","type":"module","_from":"file:bsv-teranode-listener-1.0.5.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"demo":"tsx demo.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/tmp/2242ccb05182108e1585c784fc735ad5/bsv-teranode-listener-1.0.5.tgz","_integrity":"sha512-D7wmE1AK+hd4cXikZfFm/JGWMOntlS3rmCEnUshKlt+pVil0adal8sbv3nraMFhdpEAKqiVugB92xiq61YvJeg==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.13.0","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"24.16.0","dependencies":{"libp2p":"^2.9.0","@bsv/sdk":"^2.1.4","@libp2p/tcp":"^10.1.18","@libp2p/ping":"^2.0.12","@libp2p/pnet":"^2.0.42","@libp2p/crypto":"^5.1.7","@libp2p/kad-dht":"^15.1.10","@libp2p/peer-id":"^5.0.3","@libp2p/identify":"^3.0.11","@libp2p/bootstrap":"^11.0.46","@libp2p/interface":"^3.2.2","@chainsafe/libp2p-noise":"^16.1.4","@chainsafe/libp2p-yamux":"^7.0.4","@multiformats/multiaddr":"^12.3.0","@chainsafe/libp2p-gossipsub":"^14.1.1","@libp2p/pubsub-peer-discovery":"^11.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","typescript":"^6.0.3","@types/node":"^25.9.1"},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.0.5_1781845781828_0.47875110813547517","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@bsv/teranode-listener","version":"1.1.0","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.1.0","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"7c30485ddd0ce99c027baa28b5eee08c8b36eb34","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.1.0.tgz","fileCount":8,"integrity":"sha512-m1XjVqo/cxy/QonIIx7ax+M38wbF8eDYlo1XEM7qnCxBEZEn9ZRXJ6IO4xm/SotZU2vpb01P/5Tj/OAYoa+IFw==","signatures":[{"sig":"MEQCIG+pShZHnYHO80f8KkvCs2gn3IxhmDeXyYwxqIywtQh/AiAShGQmPzslp/WYp6YimcBlsm3eJNZsQvCzrqACy6OOAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":51329},"main":"dist/index.js","type":"module","_from":"file:bsv-teranode-listener-1.1.0.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"demo":"tsx demo.ts","build":"tsc"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/tmp/39c2dc9997af01df82338b437a9a77bd/bsv-teranode-listener-1.1.0.tgz","_integrity":"sha512-m1XjVqo/cxy/QonIIx7ax+M38wbF8eDYlo1XEM7qnCxBEZEn9ZRXJ6IO4xm/SotZU2vpb01P/5Tj/OAYoa+IFw==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.13.0","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"24.16.0","dependencies":{"libp2p":"^2.9.0","@libp2p/tcp":"^10.1.18","@libp2p/ping":"^2.0.12","@libp2p/pnet":"^2.0.42","@libp2p/crypto":"^5.1.7","@libp2p/kad-dht":"^15.1.10","@libp2p/peer-id":"^5.0.3","@libp2p/identify":"^3.0.11","@libp2p/bootstrap":"^11.0.46","@libp2p/interface":"^3.2.2","@chainsafe/libp2p-noise":"^16.1.4","@chainsafe/libp2p-yamux":"^7.0.4","@multiformats/multiaddr":"^12.3.0","@chainsafe/libp2p-gossipsub":"^14.1.1","@libp2p/pubsub-peer-discovery":"^11.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.22.3","@bsv/sdk":"^2.1.3","typescript":"^6.0.3","@types/node":"^25.9.1"},"peerDependencies":{"@bsv/sdk":"^2"},"peerDependenciesMeta":{"@bsv/sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.1.0_1781899668238_0.7059696215162123","host":"s3://npm-registry-packages-npm-production"}},"1.1.1":{"name":"@bsv/teranode-listener","version":"1.1.1","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"license":"MIT","_id":"@bsv/teranode-listener@1.1.1","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"a093d81cd42ac36ee20fd4581286d0d032a8dfd7","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.1.1.tgz","fileCount":10,"integrity":"sha512-bmsKsrj4BOVu0WTns4RKWcD+7MeZZuL6q/PVkcNFx0q4PtSrEsQGH35QbUJ+JkaQqZWFNCzqZCC2WOIIZnpBCQ==","signatures":[{"sig":"MEUCIEFulvUp4atq9gccV5Ap/cMk2AfhpimBgzD3qdEITx1MAiEAwJDZLxDHEbT5cOP4gfQs+gcCBZ3Q6yhPFLCsUeLVk7s=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.1.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62368},"main":"dist/index.js","type":"module","_from":"file:bsv-teranode-listener-1.1.1.tgz","types":"dist/index.d.ts","engines":{"node":">=18.0.0"},"scripts":{"demo":"tsx demo.ts","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand","build":"tsc","test:coverage":"node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/tmp/6fcf8de0e997a4adf5e301967e8b76d5/bsv-teranode-listener-1.1.1.tgz","_integrity":"sha512-bmsKsrj4BOVu0WTns4RKWcD+7MeZZuL6q/PVkcNFx0q4PtSrEsQGH35QbUJ+JkaQqZWFNCzqZCC2WOIIZnpBCQ==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.16.0","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"_nodeVersion":"24.18.0","dependencies":{"libp2p":"^3.3.6","@libp2p/tcp":"^11.0.24","@libp2p/ping":"^3.1.9","@libp2p/pnet":"^3.0.25","@libp2p/crypto":"^5.1.21","@libp2p/kad-dht":"^16.4.0","@libp2p/peer-id":"^6.0.12","@libp2p/identify":"^4.1.10","@libp2p/bootstrap":"^12.0.27","@libp2p/interface":"^3.2.5","@chainsafe/libp2p-noise":"^17.0.0","@chainsafe/libp2p-yamux":"^8.0.1","@multiformats/multiaddr":"^13.0.3","@chainsafe/libp2p-gossipsub":"^14.1.2","@libp2p/pubsub-peer-discovery":"^12.0.0"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.1","jest":"^30.4.2","ts-jest":"^29.4.12","@bsv/sdk":"^2.2.0","typescript":"^6.0.3","@types/jest":"^30.0.0","@types/node":"^26.1.1","@jest/globals":"^30.4.1"},"peerDependencies":{"@bsv/sdk":"^2.1.6"},"peerDependenciesMeta":{"@bsv/sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.1.1_1784948681890_0.03616728644868572","host":"s3://npm-registry-packages-npm-production"}},"1.1.4":{"name":"@bsv/teranode-listener","version":"1.1.4","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"author":{"name":"BSV Blockchain Association"},"license":"SEE LICENSE IN LICENSE.txt","_id":"@bsv/teranode-listener@1.1.4","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"7948b51fa75ba3eb23135f700685204b4c73c20b","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.1.4.tgz","fileCount":9,"integrity":"sha512-BuxMIp+4n8JYlry2ghNoMC7t5jAI3Tjpmjein6DzJGjp5NH9hwF8NdPpgQMgX52GDJvMGDR4lMwCvulOw7FGEA==","signatures":[{"sig":"MEQCIEmK+SmKj9k77HK2sRfKRiy7bYeAoJ23UAiVx2l5LjznAiA6X/hgpSlQ5VCRu6BxO8hMy95EBj8IwJQyVwiBjroR1Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.1.4","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":59073},"main":"dist/index.js","type":"module","_from":"file:/home/runner/work/ts-stack/ts-stack/release-artifacts/packages/bsv-teranode-listener-1.1.4.tgz","types":"dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"demo":"tsx demo.ts","lint":"oxlint demo.ts jest.config.js src test --deny-warnings","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --watchman=false","build":"tsc","typecheck":"tsc --noEmit","pack:check":"pnpm build && node ../../../scripts/check-package-artifact.mjs . --modes esm --exports TeranodeListener,decodeMessage,startSubscriber,tryDecodeMessage","format:check":"pnpm --workspace-root exec prettier --check \"packages/network/ts-p2p/{README.md,demo.ts,jest.config.js,package.json,tsconfig.json}\" \"packages/network/ts-p2p/{src,test}/**/*.ts\"","test:coverage":"node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --watchman=false","test:property":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --watchman=false --runTestsByPath test/messages.property.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/home/runner/work/ts-stack/ts-stack/release-artifacts/packages/bsv-teranode-listener-1.1.4.tgz","_integrity":"sha512-BuxMIp+4n8JYlry2ghNoMC7t5jAI3Tjpmjein6DzJGjp5NH9hwF8NdPpgQMgX52GDJvMGDR4lMwCvulOw7FGEA==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.16.0","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"libp2p":"^3.3.7","@libp2p/tcp":"^11.0.25","@libp2p/ping":"^3.1.10","@libp2p/pnet":"^3.0.26","@libp2p/crypto":"^5.1.21","@libp2p/kad-dht":"^16.4.1","@libp2p/peer-id":"^6.0.13","@libp2p/identify":"^4.1.11","@libp2p/bootstrap":"^12.0.28","@libp2p/interface":"^3.2.5","@chainsafe/libp2p-noise":"^17.0.0","@chainsafe/libp2p-yamux":"^8.0.1","@multiformats/multiaddr":"^13.0.3","@chainsafe/libp2p-gossipsub":"^14.1.2","@libp2p/pubsub-peer-discovery":"^12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.1","jest":"^30.4.2","oxlint":"^1.76.0","ts-jest":"^29.4.12","@bsv/sdk":"^2.2.15","fast-check":"^4.9.0","typescript":"npm:@typescript/typescript6@6.0.2","@types/jest":"^30.0.0","@types/node":"^26.1.2","@jest/globals":"^30.4.1","@typescript/native":"npm:typescript@7.0.2"},"peerDependencies":{"@bsv/sdk":"^2.1.6"},"peerDependenciesMeta":{"@bsv/sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.1.4_1785457111405_0.6237941814231791","host":"s3://npm-registry-packages-npm-production"}},"1.1.5":{"name":"@bsv/teranode-listener","version":"1.1.5","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"author":{"name":"BSV Association"},"license":"SEE LICENSE IN LICENSE.txt","_id":"@bsv/teranode-listener@1.1.5","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"9fc3d27d3132c1ce290d9384376b5f9cf9f1b70d","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.1.5.tgz","fileCount":11,"integrity":"sha512-TOfSHNtsHx+CHJDczem9Zl1Owg9llUl/t7XDgFhHPl4i9FquC3YnSL+eeriM3lrwF/AMedf/0XBe/u4NNT80TQ==","signatures":[{"sig":"MEQCIBcww8YxRR5EBp25fNmJTvnotdDjR+pbM1n8tOk/6rNxAiAueGjoxPnnDnmLTzYiuvWo7BXN8PfESAmA1yomXYSNVw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.1.5","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":62686},"main":"dist/index.js","type":"module","_from":"file:/home/runner/work/ts-stack/ts-stack/release-artifacts/packages/bsv-teranode-listener-1.1.5.tgz","types":"dist/index.d.ts","engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"scripts":{"demo":"tsx demo.ts","lint":"oxlint demo.ts jest.config.js src test --deny-warnings","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --watchman=false","build":"tsc","typecheck":"tsc --noEmit","pack:check":"pnpm build && node ../../../scripts/check-package-artifact.mjs . --modes esm --exports TeranodeListener,decodeMessage,startSubscriber,tryDecodeMessage","format:check":"pnpm --workspace-root exec prettier --check \"packages/network/ts-p2p/{README.md,demo.ts,jest.config.js,package.json,tsconfig.json}\" \"packages/network/ts-p2p/{src,test}/**/*.ts\"","test:coverage":"node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --watchman=false","test:property":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --watchman=false --runTestsByPath test/messages.property.test.ts"},"_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"_resolved":"/home/runner/work/ts-stack/ts-stack/release-artifacts/packages/bsv-teranode-listener-1.1.5.tgz","_integrity":"sha512-TOfSHNtsHx+CHJDczem9Zl1Owg9llUl/t7XDgFhHPl4i9FquC3YnSL+eeriM3lrwF/AMedf/0XBe/u4NNT80TQ==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.16.0","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"libp2p":"^3.3.7","@libp2p/tcp":"^11.0.25","@libp2p/ping":"^3.1.10","@libp2p/pnet":"^3.0.26","@libp2p/crypto":"^5.1.21","@libp2p/kad-dht":"^16.4.1","@libp2p/peer-id":"^6.0.13","@libp2p/identify":"^4.1.11","@libp2p/bootstrap":"^12.0.28","@libp2p/interface":"^3.2.5","@chainsafe/libp2p-noise":"^17.0.0","@chainsafe/libp2p-yamux":"^8.0.1","@multiformats/multiaddr":"^13.0.3","@chainsafe/libp2p-gossipsub":"^14.1.2","@libp2p/pubsub-peer-discovery":"^12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.1","jest":"^30.4.2","oxlint":"^1.76.0","ts-jest":"^29.4.12","@bsv/sdk":"^2.4.2","fast-check":"^4.9.0","typescript":"npm:@typescript/typescript6@6.0.2","@types/jest":"^30.0.0","@types/node":"^26.1.2","@jest/globals":"^30.4.1","@typescript/native":"npm:typescript@7.0.2"},"peerDependencies":{"@bsv/sdk":"^2.1.6"},"peerDependenciesMeta":{"@bsv/sdk":{"optional":false}},"_npmOperationalInternal":{"tmp":"tmp/teranode-listener_1.1.5_1787866192147_0.7015906332871122","host":"s3://npm-registry-packages-npm-production"}},"1.1.6":{"_id":"@bsv/teranode-listener@1.1.6","bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"dist":{"shasum":"c473fd1753d8a410878e2e093b2958ff5ed3cd0b","tarball":"https://registry.npmjs.org/@bsv/teranode-listener/-/teranode-listener-1.1.6.tgz","fileCount":11,"integrity":"sha512-kNfv127yzoB/hM7zNZzeMWj463XQ0GR/eq9+1ho14kAltMInpbH2k3lHaC587CIaPFsb1n7N7Zdg+rSV22LObw==","signatures":[{"sig":"MEYCIQCBY0KN3S6CbD8OlhBBOzJwunj2mTha/tzAWVbzg7ZbSwIhAO93ax7n3FATqDe8Waf/pYbuR78+KI5WWW3E/n/SDSdO","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCPgoHbHGrNR2wU8sYZ0I2H2OBYkUpFlJLXW4HDFxsM/QIgYr75X1M+i1Yefw1dRn8Xu2eQNJtYGs//7cOKz7aLQgU="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@bsv%2fteranode-listener@1.1.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":85553},"main":"dist/index.js","name":"@bsv/teranode-listener","type":"module","_from":"file:/home/runner/work/ts-stack/ts-stack/release-artifacts/packages/bsv-teranode-listener-1.1.6.tgz","types":"dist/index.d.ts","author":{"name":"BSV Association"},"engines":{"node":">=22"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","default":"./dist/index.js"},"./package.json":"./package.json"},"license":"SEE LICENSE IN LICENSE.txt","scripts":{"demo":"tsx demo.ts","lint":"oxlint demo.ts jest.config.js src test --deny-warnings","test":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --watchman=false","build":"tsc","typecheck":"tsc --noEmit","pack:check":"pnpm build && node ../../../scripts/check-package-artifact.mjs . --modes esm --exports TeranodeListener,decodeMessage,startSubscriber,tryDecodeMessage","format:check":"pnpm --workspace-root exec prettier --check \"packages/network/ts-p2p/{README.md,demo.ts,jest.config.js,package.json,tsconfig.json}\" \"packages/network/ts-p2p/{src,test}/**/*.ts\"","test:coverage":"node --experimental-vm-modules node_modules/jest/bin/jest.js --coverage --runInBand --watchman=false","test:property":"node --experimental-vm-modules node_modules/jest/bin/jest.js --runInBand --watchman=false --runTestsByPath test/messages.property.test.ts"},"version":"1.1.6","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:b3a39c64-bed7-471d-82da-52a6ec6c35be"}},"homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"_resolved":"/home/runner/work/ts-stack/ts-stack/release-artifacts/packages/bsv-teranode-listener-1.1.6.tgz","_integrity":"sha512-kNfv127yzoB/hM7zNZzeMWj463XQ0GR/eq9+1ho14kAltMInpbH2k3lHaC587CIaPFsb1n7N7Zdg+rSV22LObw==","repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"_npmVersion":"11.16.0","description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","directories":{},"maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"sideEffects":false,"_nodeVersion":"24.18.0","dependencies":{"libp2p":"^3.3.7","@libp2p/tcp":"^11.0.25","@libp2p/ping":"^3.1.10","@libp2p/pnet":"^3.0.26","@libp2p/crypto":"^5.1.21","@libp2p/kad-dht":"^16.4.1","@libp2p/peer-id":"^6.0.13","@libp2p/identify":"^4.1.11","@libp2p/bootstrap":"^12.0.28","@libp2p/interface":"^3.2.5","@chainsafe/libp2p-noise":"^17.0.0","@chainsafe/libp2p-yamux":"^8.0.1","@multiformats/multiaddr":"^13.0.3","@chainsafe/libp2p-gossipsub":"^14.1.2","@libp2p/pubsub-peer-discovery":"^12.0.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsx":"^4.23.1","jest":"^30.4.2","oxlint":"^1.76.0","ts-jest":"^29.4.12","@bsv/sdk":"^2.8.0","fast-check":"^4.9.0","typescript":"npm:@typescript/typescript6@6.0.2","@types/jest":"^30.0.0","@types/node":"^26.1.2","@jest/globals":"^30.4.1","@typescript/native":"npm:typescript@7.0.2"},"peerDependencies":{"@bsv/sdk":"^2.1.6"},"peerDependenciesMeta":{"@bsv/sdk":{"optional":false}},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/teranode-listener_1.1.6_1790140370022_0.5362487506509899"}}},"time":{"created":"2025-07-27T00:53:39.968Z","modified":"2026-09-23T05:12:50.716Z","1.0.0":"2025-07-27T00:53:40.221Z","1.0.1":"2025-07-27T01:10:38.574Z","1.0.3":"2026-05-18T20:42:23.317Z","1.0.4":"2026-05-24T04:39:18.179Z","1.0.5":"2026-06-19T05:09:41.961Z","1.1.0":"2026-06-19T20:07:48.409Z","1.1.1":"2026-07-25T03:04:42.023Z","1.1.4":"2026-07-31T00:18:31.551Z","1.1.5":"2026-08-27T21:29:52.290Z","1.1.6":"2026-09-23T05:12:50.105Z"},"bugs":{"url":"https://github.com/bsv-blockchain/ts-stack/issues"},"author":{"name":"BSV Association"},"license":"SEE LICENSE IN LICENSE.txt","homepage":"https://github.com/bsv-blockchain/ts-stack/tree/main/packages/network/ts-p2p#readme","keywords":["teranode","libp2p","p2p","private-network","dht","pubsub","bsv"],"repository":{"url":"git+https://github.com/bsv-blockchain/ts-stack.git","type":"git","directory":"packages/network/ts-p2p"},"description":"An npm package to subscribe to Teranode P2P topics in a private DHT network and log messages","maintainers":[{"name":"johngalt5","email":"dylan@murraydt.com"},{"name":"loftsteinn","email":"oli@oskarsson.nl"},{"name":"dkellen","email":"darrkellen@gmail.com"},{"name":"braydude","email":"brayden167@gmail.com"},{"name":"tyeverett","email":"p2ppsr@tyweb.us"}],"readme":"# @bsv/teranode-listener\n\nBSV BLOCKCHAIN | A TypeScript library for subscribing to Teranode P2P topics over libp2p\n\nA robust npm package that enables subscription to Teranode P2P topics using libp2p with private network support, DHT, and gossipsub messaging.\n\n## Table of Contents\n\n1. [Overview](#overview)\n2. [Installation](#installation)\n3. [Getting Started](#getting-started)\n4. [API Reference](#api-reference)\n5. [Configuration](#configuration)\n6. [Examples](#examples)\n7. [Development](#development)\n8. [Contributing](#contributing)\n9. [Support & Contacts](#support--contacts)\n\n## Overview\n\nThe `@bsv/teranode-listener` package provides a simple yet powerful interface for connecting to the Teranode P2P network. It handles:\n\n- **PNET compatibility**: Connect with the public Teranode mainnet PNET value or a private deployment's own PSK\n- **DHT Integration**: Distributed hash table for peer discovery\n- **Topic Subscription**: Subscribe to specific topics and receive real-time messages\n- **Peer Management**: Automatic peer discovery and connection management\n- **Message Logging**: Built-in logging for network events and messages\n\n## Installation\n\n```bash\nnpm install @bsv/teranode-listener\n```\n\n### Requirements\n\n- **Node.js**: Version 22.0.0 or higher\n- **ES Modules**: This package is published as an ES module. Ensure your project supports ES modules by either:\n  - Adding `\"type\": \"module\"` to your `package.json`, or\n  - Using `.mjs` file extensions for your JavaScript files\n\n## Getting Started\n\n### Callback-Based API (Recommended)\n\nThe easiest way to use the library is with the `TeranodeListener` class, which provides topic-specific callbacks:\n\n```typescript\nimport { TeranodeListener } from '@bsv/teranode-listener'\n\n// Define callback functions for different topics\nconst blockCallback = (data: Uint8Array, topic: string, from: string) => {\n  console.log(`New block received from ${from}:`, data)\n  // Process block data here\n}\n\nconst subtreeCallback = (data: Uint8Array, topic: string, from: string) => {\n  console.log(`Subtree update from ${from}:`, data)\n  // Process subtree data here\n}\n\n// Create listener with topic callbacks\nconst listener = new TeranodeListener({\n  'bitcoin/mainnet-block': blockCallback,\n  'bitcoin/mainnet-subtree': subtreeCallback\n})\n\n// Start the listener and connect to Teranode mainnet\nawait listener.start()\nconsole.log('Listener started and waiting for messages...')\n```\n\n### Decoding messages\n\nBy default, callbacks receive the raw GossipSub bytes (`Uint8Array`). Pass `decodeMessages: true` to have the listener perform bounded, canonical two-layer JSON decoding. Callbacks then receive a `DecodedMessage` (the unverified sender-name field plus a structurally safe payload). TypeScript payload types are compile-time aids, not schema validation or proof of publisher identity:\n\n```typescript\nimport { TeranodeListener, type BlockMessage, type DecodedMessage } from '@bsv/teranode-listener'\n\nconst listener = new TeranodeListener(\n  {\n    'bitcoin/mainnet-block': (msg: DecodedMessage<BlockMessage>, topic, from) => {\n      console.log(`Block #${msg.payload.Height} (${msg.payload.Hash}) from ${msg.sender}`)\n    }\n  },\n  { decodeMessages: true }\n)\n\nawait listener.start()\n```\n\nThe exported `decodeMessage()` / `tryDecodeMessage()` helpers can also be used to decode a message manually. Frames that are not valid JSON (e.g. libp2p control frames) are skipped when `decodeMessages` is on.\n\nListener construction snapshots and validates the supplied callbacks,\nconfiguration, topic list, and address arrays. Later caller mutation cannot\nsilently change the network or decoding policy, and boolean controls accept\nonly literal booleans. Concurrent `start()` or `stop()` calls share one\nlifecycle transition; a failed start cleans up its partial node and may be\nretried.\n\n### Function-Based API\n\nAlternatively, you can use the original function-based API:\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\n// Start with selected topics (or omit the argument for all mainnet topics).\nawait startSubscriber({\n  topics: ['bitcoin/mainnet-block', 'bitcoin/mainnet-subtree']\n})\n\nconsole.log('Subscriber started and listening for messages...')\n```\n\nOnce started, both approaches automatically:\n\n- Connect to the official Teranode bootstrap peer\n- Use the mainnet shared key\n- Listen on `127.0.0.1:9901`\n- Connect to known active Teranode peers\n\n### Custom Configuration\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\nconst config = {\n  topics: ['bitcoin/mainnet-block'], // Only subscribe to blocks\n  listenAddresses: ['/ip4/0.0.0.0/tcp/4000'] // Listen on a different port\n}\n\n// Start with custom topics and port\nawait startSubscriber(config)\nconsole.log('Subscriber started with custom configuration...')\n```\n\n### Complete Custom Setup\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\nconst config = {\n  bootstrapPeers: ['/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWExample1'],\n  staticPeers: [\n    '/ip4/192.168.1.100/tcp/4003/p2p/12D3KooWStatic1',\n    '/ip4/192.168.1.101/tcp/4003/p2p/12D3KooWStatic2'\n  ],\n  sharedKey: 'your-custom-hex-shared-key-here',\n  topics: ['bitcoin/testnet-block', 'bitcoin/testnet-subtree'],\n  listenAddresses: ['/ip4/0.0.0.0/tcp/4000'],\n  dhtProtocolID: '/custom-protocol'\n}\n\nawait startSubscriber(config)\n```\n\nFor more detailed examples, check our [Examples](#examples) section.\n\n## API Reference\n\n### `TeranodeListener` Class (Recommended)\n\nThe primary API for subscribing to Teranode P2P topics with callback functions.\n\n#### Constructor\n\n```typescript\nnew TeranodeListener(topicCallbacks: TopicCallbacks, config?: TeranodeListenerConfig)\n```\n\n**Parameters:**\n\n- `topicCallbacks` - Object mapping topic names to callback functions\n- `config` - Optional configuration (uses Teranode mainnet defaults)\n\n**Example:**\n\n```typescript\nconst listener = new TeranodeListener({\n  'bitcoin/mainnet-block': (data, topic, from) => {\n    console.log('Block received:', data)\n  },\n  'bitcoin/mainnet-subtree': (data, topic, from) => {\n    console.log('Subtree update:', data)\n  }\n})\n\n// Start the listener (it does not start automatically)\nawait listener.start()\n```\n\n#### Methods\n\n- `start(): Promise<void>` - Start the listener and connect to Teranode peers (must be called after construction)\n- `addTopicCallback(topic: Topic, callback: MessageCallback): void` - Add a new topic subscription\n- `removeTopicCallback(topic: Topic): void` - Remove a topic subscription\n- `stop(): Promise<void>` - Stop the listener\n- `getNode(): Libp2p | null` - Get the underlying libp2p node\n- `getConnectedPeerCount(): number` - Get number of connected peers\n\n#### Types\n\n```typescript\n// Supported Teranode P2P topics\nexport type Topic =\n  | 'bitcoin/mainnet-bestblock' // Best block message\n  | 'bitcoin/mainnet-block' // When miners find a block solution\n  | 'bitcoin/mainnet-subtree' // When a subtree is created\n  | 'bitcoin/mainnet-mining_on' // When mining is enabled\n  | 'bitcoin/mainnet-handshake' // When a peer connects to the network\n  | 'bitcoin/mainnet-rejected_tx' // When a transaction is rejected\n\ntype MessageCallback = (data: Uint8Array, topic: Topic, from: string) => void\ntype TopicCallbacks = Partial<Record<Topic, MessageCallback>>\n\ninterface TeranodeListenerConfig {\n  bootstrapPeers?: string[] // Bootstrap peer multiaddrs (default: Teranode mainnet bootstrap)\n  staticPeers?: string[] // Static peer multiaddrs (default: Known Teranode mainnet peers)\n  sharedKey?: string // Hex string of PSK (default: Teranode mainnet key)\n  dhtProtocolID?: string // DHT protocol prefix (default: '/teranode')\n  listenAddresses?: string[] // Listen addresses (default: ['/ip4/127.0.0.1/tcp/9901'])\n  usePrivateDHT?: boolean // Whether to use private DHT (default: true)\n}\n```\n\n### `startSubscriber(config?: SubscriberConfig): Promise<void>`\n\nLegacy function-based API for subscribing to topics.\n\n#### Parameters\n\n- `config` - Optional configuration object for the subscriber. If not provided, uses mainnet defaults.\n\n#### Returns\n\nA Promise that resolves when the subscriber is successfully started.\n\n### `SubscriberConfig`\n\nConfiguration interface for the function-based API. All parameters are optional:\n\n```typescript\ninterface SubscriberConfig {\n  bootstrapPeers?: string[] // Bootstrap peer multiaddrs (default: Teranode mainnet bootstrap)\n  staticPeers?: string[] // Static peer multiaddrs (default: Known Teranode mainnet peers)\n  sharedKey?: string // Hex string of PSK (default: Teranode mainnet key)\n  dhtProtocolID?: string // DHT protocol prefix (default: '/teranode')\n  topics?: Topic[] // Topics to subscribe to (default: all Teranode topics)\n  listenAddresses?: string[] // Listen addresses (default: ['/ip4/127.0.0.1/tcp/9901'])\n  usePrivateDHT?: boolean // Whether to use private DHT (default: true)\n}\n```\n\n## Configuration\n\n### Default Configuration\n\nThe package comes with production-ready defaults for Teranode mainnet:\n\n- **`bootstrapPeers`**: `['/dns4/teranode-bootstrap.bsvb.tech/tcp/9901/p2p/12D3KooWESmhNAN8s6NPdGNvJH3zJ4wMKDxapXKNUe2DzkAwKYqK']`\n- **`staticPeers`**: Array of known active Teranode mainnet peers (TAAL, BSVB, etc.)\n- **`sharedKey`**: public 32-byte Teranode mainnet PNET compatibility value\n- **`topics`**: all six `bitcoin/mainnet-*` topics listed in the `Topic` type\n- **`listenAddresses`**: `['/ip4/127.0.0.1/tcp/9901']`\n- **`dhtProtocolID`**: `/teranode`\n- **`usePrivateDHT`**: `true`\n\n### Customizable Parameters\n\nAll parameters are optional and can be overridden:\n\n- **`bootstrapPeers`**: Array of multiaddr strings for initial peer discovery\n- **`staticPeers`**: Additional peers to maintain persistent connections with\n- **`sharedKey`**: exactly 64 hexadecimal characters representing a 32-byte PNET value\n- **`topics`**: Array of topic strings to subscribe to\n- **`listenAddresses`**: Network addresses to listen on\n- **`dhtProtocolID`**: Custom DHT protocol identifier\n- **`usePrivateDHT`**: Whether to enable the Kademlia DHT service; `false` now omits that network service entirely\n\n### Pre-Shared Key Format\n\nThe `sharedKey` should be provided as a hexadecimal string without the PSK headers. The library automatically formats it as:\n\n```\n/key/swarm/psk/1.0.0/\n/base16/\n<your-hex-key>\n```\n\nThe default mainnet value is published in this package so every consumer can\njoin the same network. It is not a secret, membership credential, peer\nallowlist, or message signature. PNET and Noise protect compatible transport;\nthey do not make a received event authoritative. A custom network can use a\nsecret PSK to restrict initial membership, but applications must still verify\nsecurity-critical transaction, block, and chain claims independently.\n\n## Examples\n\n### Example 1: Basic TeranodeListener Usage\n\n```typescript\nimport { TeranodeListener, type Topic } from '@bsv/teranode-listener'\n\n// Simple callback-based listener\nconst listener = new TeranodeListener({\n  'bitcoin/mainnet-block': (data: Uint8Array, topic: Topic, from: string) => {\n    console.log(`New block from ${from}:`, data.length, 'bytes')\n    // Process block data\n  },\n  'bitcoin/mainnet-subtree': (data: Uint8Array, topic: Topic, from: string) => {\n    console.log(`Subtree update from ${from}:`, data.length, 'bytes')\n    // Process subtree data\n  }\n})\n\nawait listener.start()\nconsole.log('Listener started, waiting for messages...')\n```\n\n### Example 2: Advanced TeranodeListener with Custom Configuration\n\n```typescript\nimport { TeranodeListener } from '@bsv/teranode-listener'\n\n// Create a listener with topic-specific callbacks\nconst listener = new TeranodeListener({\n  'bitcoin/mainnet-block': (data, topic, from) => {\n    console.log(`Received block from ${from}:`, data)\n  },\n  'bitcoin/mainnet-subtree': (data, topic, from) => {\n    console.log(`Received subtree from ${from}:`, data)\n  }\n})\n\nawait listener.start()\nconsole.log('Connected peers:', listener.getConnectedPeerCount())\n\n// Add more topics dynamically\nlistener.addTopicCallback('bitcoin/mainnet-rejected_tx', (data, topic, from) => {\n  console.log(`Received rejection from ${from}:`, data)\n})\n\n// Monitor connection status\nsetInterval(() => {\n  console.log('Connected peers:', listener.getConnectedPeerCount())\n}, 30000)\n```\n\n### Example 3: Function-Based API (Legacy)\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\n// Connect to Teranode mainnet with all defaults\nstartSubscriber()\n  .then(() => console.log('Connected to Teranode mainnet!'))\n  .catch(console.error)\n```\n\n### Example 4: Custom Port and Multiple Topics (Function API)\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\n// Use a different port and subscribe to multiple topics\nconst config = {\n  topics: ['bitcoin/mainnet-block', 'bitcoin/mainnet-subtree', 'bitcoin/mainnet-rejected_tx'],\n  listenAddresses: ['/ip4/0.0.0.0/tcp/4000']\n}\n\nawait startSubscriber(config)\nconsole.log('Listening on port 4000 for blocks, subtrees, and rejected transactions...')\n```\n\n### Example 5: Environment-Based Configuration\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\nconst config = {\n  topics: process.env.TOPICS?.split(',') || undefined, // Use defaults if not set\n  listenAddresses: process.env.LISTEN_ADDRESS ? [process.env.LISTEN_ADDRESS] : undefined,\n  sharedKey: process.env.CUSTOM_SHARED_KEY || undefined // Use default mainnet key if not set\n}\n\n// Start with environment overrides, falling back to defaults\nawait startSubscriber(config)\nconsole.log('Started with environment configuration...')\n```\n\n### Example 6: Complete Custom Network\n\n```typescript\nimport { startSubscriber } from '@bsv/teranode-listener'\n\n// Connect to a custom private network\nconst config = {\n  bootstrapPeers: [\n    '/ip4/10.0.0.1/tcp/4001/p2p/12D3KooWBootstrap1',\n    '/ip4/10.0.0.2/tcp/4001/p2p/12D3KooWBootstrap2'\n  ],\n  staticPeers: ['/ip4/10.0.0.10/tcp/4003/p2p/12D3KooWStatic1'],\n  sharedKey: 'your-custom-private-network-key',\n  dhtProtocolID: '/custom-network',\n  topics: ['bitcoin/testnet-block', 'bitcoin/testnet-subtree'],\n  listenAddresses: ['/ip4/0.0.0.0/tcp/4000'],\n  usePrivateDHT: true\n}\n\nawait startSubscriber(config)\nconsole.log('Connected to custom private network...')\n```\n\n## Security boundary\n\n- Treat every topic, envelope sender name, and payload field as untrusted.\n- The callback `from` value is the libp2p propagation peer, which may be a\n  relay; it is not proof that the peer authored the application payload.\n- `decodeMessages` bounds and structurally validates JSON, but it does not\n  authenticate a publisher or validate each topic-specific schema.\n- The internal subtree-format implementation bounds node and byte counts,\n  preserves exact unsigned 64-bit values, and verifies aggregate totals,\n  conflicts, and the canonical Bitcoin Merkle root before accepting bytes.\n  These checks establish internal consistency, not who authored a subtree.\n- Verify hashes, headers, transactions, Merkle evidence, heights, and chain\n  state through an independent trusted chain tracker before changing durable\n  or financial state.\n- Keep the default loopback listen address unless inbound P2P reachability is\n  explicitly required and protected at the network edge.\n\n## Development\n\n### Building from Source\n\n```bash\n# Clone the repository\ngit clone https://github.com/bsv-blockchain/ts-stack.git\ncd ts-stack\n\n# Install dependencies\npnpm install\n\n# Run the package contract\npnpm --filter @bsv/teranode-listener format:check\npnpm --filter @bsv/teranode-listener lint\npnpm --filter @bsv/teranode-listener typecheck\npnpm --filter @bsv/teranode-listener test:coverage\npnpm --filter @bsv/teranode-listener pack:check\n```\n\n### Testing\n\nThis package uses [Jest](https://jestjs.io/) with `ts-jest`. Run the suite with:\n\n```bash\npnpm --filter @bsv/teranode-listener test\n```\n\nThe tests exercise message decoding, subtree construction and mutation,\nlistener lifecycle, subscriptions, peer reconnection, callback isolation, and\nclean shutdown. Coverage thresholds enforce the package's measured baseline.\n`pack:check` installs the exact ESM tarball and verifies its public exports.\n\n### Project Structure\n\n```\nts-p2p/\n├── src/\n│   ├── index.ts          # Main library and listener\n│   ├── subtrees.ts       # Subtree data structure and validation\n│   └── messages.ts       # Wire-format types and decoder\n├── test/\n│   ├── index.test.ts     # Listener lifecycle and peer behavior\n│   ├── messages.test.ts  # Decoder test suite\n│   └── subtrees.test.ts  # Subtree behavior and validation\n├── dist/                 # Compiled JavaScript output\n├── jest.config.js        # Jest (ts-jest) configuration\n├── package.json          # Package configuration\n├── tsconfig.json         # TypeScript configuration\n└── README.md             # This file\n```\n\n### Dependencies\n\nThis package relies on several key libp2p modules:\n\n- **libp2p**: Core P2P networking library\n- **@chainsafe/libp2p-gossipsub**: Gossip-based pub/sub messaging\n- **@libp2p/kad-dht**: Kademlia DHT for peer discovery\n- **@libp2p/pnet**: Private network support with PSK\n- **@chainsafe/libp2p-noise**: Noise protocol for secure connections\n\n## Contributing\n\nWe welcome contributions to improve the `@bsv/teranode-listener` package. Whether it's bug reports, feature requests, or pull requests - all contributions are appreciated.\n\n### How to Contribute\n\n1. **Fork the repository** - Start by forking the project repository to your GitHub account\n2. **Clone the repository** - Clone the forked repository to your local machine\n3. **Create a new branch** - Create a new branch for your feature or bug fix\n4. **Make your changes** - Implement your changes with appropriate tests\n5. **Build and test** - Ensure the project builds and all tests pass\n6. **Submit a pull request** - Submit a pull request with a clear description\n\n### Development Guidelines\n\n- Follow TypeScript best practices\n- Maintain backward compatibility when possible\n- Add tests for new features\n- Update documentation as needed\n- Follow the existing code style and conventions\n\n## Support & Contacts\n\nProject Maintainers:\n\n- [BSV Blockchain](https://github.com/bitcoin-sv)\n\nFor questions, bug reports, or feature requests:\n\n- [Open an issue](https://github.com/bsv-blockchain/ts-stack/issues) on GitHub\n- Check existing [documentation](https://docs.bsvblockchain.org/)\n\n---\n\n## License\n\nTS Stack first-party changes are under the [Open BSV License Version 6](./LICENSE.txt).\nThe recovered pre-monorepo MIT notice is retained in\n[THIRD_PARTY_NOTICES.md](./THIRD_PARTY_NOTICES.md) and [LICENSES/](./LICENSES/).\n\nThank you for being a part of the BSV Blockchain ecosystem. Let's build the future of BSV Blockchain together!\n","readmeFilename":"README.md"}