<inputclass="md-option"data-md-color-media=""data-md-color-scheme="default"data-md-color-primary="blue-grey"data-md-color-accent=""aria-label="Switch to dark mode"type="radio"name="__palette"id="__palette_1">
<labelclass="md-header__button md-icon"title="Switch to dark mode"for="__palette_2"hidden>
<inputclass="md-option"data-md-color-media=""data-md-color-scheme="slate"data-md-color-primary="blue-grey"data-md-color-accent=""aria-label="Switch to light mode"type="radio"name="__palette"id="__palette_2">
<labelclass="md-header__button md-icon"title="Switch to light mode"for="__palette_1"hidden>
<p>Hi all, welcome to the first nim-libp2p tutorial!</p>
<divclass="admonition tips">
<p>This tutorial is for everyone who is interested in building peer-to-peer applications. No Nim programming experience is needed.</p>
</div>
<p>To give you a quick overview, <strong>Nim</strong> is the programming language we are using and <strong>nim-libp2p</strong> is the Nim implementation of <ahref="https://libp2p.io/">libp2p</a>, a modular library that enables the development of peer-to-peer network applications.</p>
<p>Hope you'll find it helpful in your journey of learning. Happy coding! ;)</p>
<h2id="before-you-start">Before you start</h2>
<p>The only prerequisite here is <ahref="https://nim-lang.org/">Nim</a>, the programming language with a Python-like syntax and a performance similar to C. Detailed information can be found <ahref="https://nim-lang.org/docs/tut1.html">here</a>.</p>
<p>Install Nim via their <ahref="https://nim-lang.org/install.html">official website</a>.
Check Nim's installation via <code>nim --version</code> and its package manager Nimble via <code>nimble --version</code>.</p>
<p>You can now install the latest version of <code>nim-libp2p</code>:
<p>We'll start by creating a simple application, which is starting two libp2p <ahref="https://docs.libp2p.io/concepts/stream-multiplexing/#switch-swarm">switch</a>, and pinging each other using the <ahref="https://docs.libp2p.io/concepts/protocols/#ping">Ping</a> protocol.</p>
<divclass="admonition tips">
<p>You can find the source of this tutorial (and other tutorials) in the <ahref="https://github.com/status-im/nim-libp2p/tree/master/examples">libp2p/examples</a> folder!</p>
</div>
<p>Let's create a <code>part1.nim</code>, and import our dependencies:
<ahref="https://github.com/status-im/nim-chronos">chronos</a> the asynchronous framework used by <code>nim-libp2p</code></p>
<p>Next, we'll create an helper procedure to create our switches. A switch needs a bit of configuration, and it will be easier to do this configuration only once:
<aid="__codelineno-2-4"name="__codelineno-2-4"href="#__codelineno-2-4"></a><spanclass="p">.</span><spanclass="n">withRng</span><spanclass="p">(</span><spanclass="n">rng</span><spanclass="p">)</span><spanclass="c"># Give the application RNG</span>
<aid="__codelineno-2-5"name="__codelineno-2-5"href="#__codelineno-2-5"></a><spanclass="p">.</span><spanclass="n">withAddress</span><spanclass="p">(</span><spanclass="n">ma</span><spanclass="p">)</span><spanclass="c"># Our local address(es)</span>
<aid="__codelineno-2-6"name="__codelineno-2-6"href="#__codelineno-2-6"></a><spanclass="p">.</span><spanclass="n">withTcpTransport</span><spanclass="p">()</span><spanclass="c"># Use TCP as transport</span>
<aid="__codelineno-2-7"name="__codelineno-2-7"href="#__codelineno-2-7"></a><spanclass="p">.</span><spanclass="n">withMplex</span><spanclass="p">()</span><spanclass="c"># Use Mplex as muxer</span>
<aid="__codelineno-2-8"name="__codelineno-2-8"href="#__codelineno-2-8"></a><spanclass="p">.</span><spanclass="n">withNoise</span><spanclass="p">()</span><spanclass="c"># Use Noise as secure manager</span>
This will create a switch using <ahref="https://docs.libp2p.io/concepts/stream-multiplexing/">Mplex</a> as a multiplexer, Noise to secure the communication, and TCP as an underlying transport.</p>
<p>You can of course tweak this, to use a different or multiple transport, or tweak the configuration of Mplex and Noise, but this is some sane defaults that we'll use going forward.</p>
We created some variables that we'll need for the rest of the application: the global <code>rng</code> instance, our <code>localAddress</code>, and an instance of the <code>Ping</code> protocol.
The address is in the <ahref="https://github.com/multiformats/multiaddr">MultiAddress</a> format. The port <code>0</code> means "take any port available".</p>
<p><code>tryGet</code> is procedure which is part of <ahref="https://github.com/arnetheduck/nim-result/">nim-result</a>, that will throw an exception if the supplied MultiAddress is invalid.</p>
We've <strong>mounted</strong> the <code>pingProtocol</code> on our first switch. This means that the first switch will actually listen for any ping requests coming in, and handle them accordingly.</p>
<p>Now that we've started the nodes, they are listening for incoming peers.
We can find out which port was attributed, and the resulting local addresses, by using <code>switch1.peerInfo.addrs</code>.</p>
<p>We'll <strong>dial</strong> the first switch from the second one, by specifying it's <strong>Peer ID</strong>, it's <strong>MultiAddress</strong> and the <strong><code>Ping</code> protocol codec</strong>:
We now have a <code>Ping</code> connection setup between the second and the first switch, we can use it to actually ping the node:
<divclass="highlight"><pre><span></span><code><aid="__codelineno-6-1"name="__codelineno-6-1"href="#__codelineno-6-1"></a><spanclass="c"># ping the other node and echo the ping duration</span>
<aid="__codelineno-6-4"name="__codelineno-6-4"href="#__codelineno-6-4"></a><spanclass="c"># We must close the connection ourselves when we're done with it</span>
And that's it! Just a little bit of cleanup: shutting down the switches, waiting for them to stop, and we'll call our <code>main</code> procedure:
<divclass="highlight"><pre><span></span><code><aid="__codelineno-7-1"name="__codelineno-7-1"href="#__codelineno-7-1"></a><spanclass="n">await</span><spanclass="n">allFutures</span><spanclass="p">(</span><spanclass="n">switch1</span><spanclass="p">.</span><spanclass="n">stop</span><spanclass="p">(),</span><spanclass="n">switch2</span><spanclass="p">.</span><spanclass="n">stop</span><spanclass="p">())</span><spanclass="c"># close connections and shutdown all transports</span>
<scriptid="__config"type="application/json">{"base":"..","features":["navigation.instant","search.highlight"],"search":"../assets/javascripts/workers/search.16e2a7d4.min.js","translations":{"clipboard.copied":"Copied to clipboard","clipboard.copy":"Copy to clipboard","search.config.lang":"en","search.config.pipeline":"trimmer, stopWordFilter","search.config.separator":"[\\s\\-]+","search.placeholder":"Search","search.result.more.one":"1 more on this page","search.result.more.other":"# more on this page","search.result.none":"No matching documents","search.result.one":"1 matching document","search.result.other":"# matching documents","search.result.placeholder":"Type to start searching","search.result.term.missing":"Missing","select.version.title":"Select version"}}</script>