Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save sloev/2822984244330fdefcba39ddfa357428 to your computer and use it in GitHub Desktop.

Select an option

Save sloev/2822984244330fdefcba39ddfa357428 to your computer and use it in GitHub Desktop.
ipfs gossip libp2p nodejs example server with http api
'use strict'
const Libp2p = require('libp2p')
const IPFS = require('ipfs')
const TCP = require('libp2p-tcp')
const MulticastDNS = require('libp2p-mdns')
const Bootstrap = require('libp2p-bootstrap')
const KadDHT = require('libp2p-kad-dht')
const MPLEX = require('libp2p-mplex')
const SECIO = require('libp2p-secio')
const GossipSub = require("libp2p-gossipsub");
const WebRTCStar = require("libp2p-webrtc-star");
const wrtc = require("wrtc");
const HttpApi = require('ipfs/src/http');
/**
* Options for the libp2p bundle
* @typedef {Object} libp2pBundle~options
* @property {PeerId} peerId - The PeerId of the IPFS node
* @property {Object} config - The config of the IPFS node
* @property {Object} options - The options given to the IPFS node
*/
/**
* This is the bundle we will use to create our fully customized libp2p bundle.
*
* @param {libp2pBundle~options} opts The options to use when generating the libp2p node
* @returns {Libp2p} Our new libp2p node
*/
const libp2pBundle = (opts) => {
// Set convenience variables to clearly showcase some of the useful things that are available
const peerId = opts.peerId
const bootstrapList = opts.config.Bootstrap
// Build and return our libp2p node
// n.b. for full configuration options, see https://github.com/libp2p/js-libp2p/blob/master/doc/CONFIGURATION.md
return new Libp2p({
peerId,
addresses: {
listen: ['/ip4/127.0.0.1/tcp/0']
},
// Lets limit the connection managers peers and have it check peer health less frequently
connectionManager: {
minPeers: 25,
maxPeers: 100,
pollInterval: 5000
},
modules: {
transport: [
WebRTCStar,
TCP
],
streamMuxer: [
MPLEX
],
connEncryption: [
SECIO
],
peerDiscovery: [
MulticastDNS,
Bootstrap
],
dht: KadDHT,
pubsub: GossipSub
},
config: {
transport: {
[WebRTCStar.prototype[Symbol.toStringTag]]: {
wrtc,
},
},
peerDiscovery: {
autoDial: true, // auto dial to peers we find when we have less peers than `connectionManager.minPeers`
mdns: {
interval: 10000,
enabled: true
},
bootstrap: {
interval: 30e3,
enabled: true,
list: bootstrapList
}
},
// Turn on relay with hop active so we can connect to more peers
relay: {
enabled: true,
hop: {
enabled: true,
active: true
}
},
dht: {
enabled: true,
kBucketSize: 20,
randomWalk: {
enabled: true,
interval: 10e3, // This is set low intentionally, so more peers are discovered quickly. Higher intervals are recommended
timeout: 2e3 // End the query quickly since we're running so frequently
}
},
pubsub: {
enabled: true
}
},
metrics: {
enabled: true,
computeThrottleMaxQueueSize: 1000, // How many messages a stat will queue before processing
computeThrottleTimeout: 2000, // Time in milliseconds a stat will wait, after the last item was added, before processing
movingAverageIntervals: [ // The moving averages that will be computed
60 * 1000, // 1 minute
5 * 60 * 1000, // 5 minutes
15 * 60 * 1000 // 15 minutes
],
maxOldPeersRetention: 50 // How many disconnected peers we will retain stats for
}
})
}
async function main () {
// Now that we have our custom libp2p bundle, let's start up the ipfs node!
const ipfsOpts = {
libp2p: libp2pBundle,
config: {
Addresses: {
API: "/ip4/127.0.0.1/tcp/9001",
Gateway: "/ip4/127.0.0.1/tcp/9002",
Swarm: [
'/dns4/wrtc-star.discovery.libp2p.io/tcp/443/wss/p2p-webrtc-star'
]
}
}
}
const node = await IPFS.create(ipfsOpts);
const httpApi = new HttpApi(node, ipfsOpts)
await httpApi.start()
httpApi._apiServers.forEach(apiServer => {
console.log(`API listening on ${apiServer.info.ma}`)
})
// Lets log out the number of peers we have every 2 seconds
setInterval(async () => {
try {
const peers = await node.swarm.peers()
console.log(`The node now has ${peers.length} peers.`)
} catch (err) {
console.log('An error occurred trying to check our peers:', err)
}
}, 2000)
// Log out the bandwidth stats every 4 seconds so we can see how our configuration is doing
setInterval(async () => {
const content = String(Math.random() + Date.now())
const file = await node.add(content)
console.log("added file", file)
try {
const stats = await node.stats.bw();
console.log(`\nBandwidth Stats: ${JSON.stringify(stats, null, 2)}\n`);
} catch (err) {
console.log("An error occurred trying to check our stats:", err);
}
}, 10000);
}
main()
{
"name": "example-custom-libp2p",
"description": "Customizing your libp2p node",
"version": "1.0.0",
"main": "main.js",
"private": true,
"scripts": {
"start": "node main.js",
"test": "test-ipfs-example"
},
"license": "MIT",
"dependencies": {
"ipfs": "^0.50.1",
"libp2p": "^0.29.0",
"libp2p-bootstrap": "^0.12.0",
"libp2p-gossipsub": "^0.6.1",
"libp2p-kad-dht": "^0.20.0",
"libp2p-mdns": "^0.15.0",
"libp2p-mplex": "^0.10.0",
"libp2p-secio": "^0.13.0",
"libp2p-tcp": "^0.15.0",
"libp2p-webrtc-star": "^0.20.1",
"wrtc": "^0.4.6"
},
"devDependencies": {
"execa": "^4.0.0",
"test-ipfs-example": "^2.0.3"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment