Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
c3ff17b
feat(js-peer): integrate-identity-and-tcp-lessons
Nkovaturient Jun 24, 2025
90c4d8b
Update scripts.md
Nkovaturient Jun 24, 2025
6dc0b39
feat(js-workshop): add lessons 1–3, deps.py + setup.md
Nkovaturient Jun 25, 2025
9e89754
resolve-merge-conflicts
Nkovaturient Jun 25, 2025
ee907a5
add to lesson
luu-alex Jun 26, 2025
46a0a47
Merge pull request #1 from luu-alex/update/js-peer-workshop
Nkovaturient Jun 26, 2025
73a1aca
update docker files
luu-alex Jun 29, 2025
96837d2
update setup
luu-alex Jun 29, 2025
31a61f3
Merge branch 'feat/js-peer-workshop' into update/js-peer-workshop
luu-alex Jun 29, 2025
7a9cd3e
Merge pull request #2 from luu-alex/update/js-peer-workshop
Nkovaturient Jun 29, 2025
90caa7a
Merge branch 'main' of https://github.com/Nkovaturient/universal-conn…
Nkovaturient Jul 2, 2025
313df97
update check and docker files
luu-alex Jul 3, 2025
2e56d66
Merge pull request #3 from luu-alex/update/js-peer-workshop
luu-alex Jul 9, 2025
f625cd9
feat(js-peer):setup lesson-4-to-6 + modify check.py
Nkovaturient Jul 10, 2025
33aa757
Merge branch 'feat/js-peer-workshop' of https://github.com/Nkovaturie…
Nkovaturient Jul 10, 2025
750e5b8
update index.js
luu-alex Jul 13, 2025
84b94b7
Merge remote-tracking branch 'upstream/main' into update/js-peer-work…
luu-alex Jul 13, 2025
ecbacc3
Merge branch 'feat/js-peer-workshop' into update/js-peer-workshop
luu-alex Jul 13, 2025
501848f
update, add more information to lesson and be compatible with docker
luu-alex Jul 15, 2025
9882456
Merge pull request #4 from luu-alex/update/js-peer-workshop
luu-alex Jul 15, 2025
2ae19ac
update lesson three
luu-alex Jul 21, 2025
5d19fe2
Merge pull request #5 from luu-alex/update/js-peer-workshop
luu-alex Jul 21, 2025
84da592
update lesson 1
luu-alex Jul 24, 2025
777568a
Merge pull request #6 from luu-alex/update/js-peer-workshop
luu-alex Jul 24, 2025
9bd4c79
update lesson 2
luu-alex Jul 24, 2025
303b552
Merge pull request #7 from luu-alex/update/js-peer-workshop
luu-alex Jul 24, 2025
303323c
Merge branch 'libp2p:main' into feat/js-peer-workshop
Nkovaturient Aug 1, 2025
db29c68
chore: update js workshop setup and remove test scripts
Nkovaturient Aug 1, 2025
b63b134
Merge branch 'feat/js-peer-workshop' of https://github.com/Nkovaturie…
Nkovaturient Aug 1, 2025
7e36f33
Lesson-3 Fixes
parth-soni07 Aug 9, 2025
e7dc904
Minor fixes to console logs
parth-soni07 Aug 16, 2025
98c9956
fix: lesson-3
Nkovaturient Aug 17, 2025
85ca2c3
fix(l5): Identify-Protocol-checkpoint
Hany-Almnaem Aug 24, 2025
48e286e
fix: lesson-5 (#11)
Nkovaturient Aug 24, 2025
87f657f
chore(docker):L3+4 docker config and refactoring
parth-soni07 Aug 26, 2025
c71e1e9
feat: add JavaScript Lesson 6 - GossipSub Pub/Sub
Hany-Almnaem Aug 27, 2025
669e5a9
Merge branch 'lesson-6-gossipsub' into addlesson6-on-workshop
Hany-Almnaem Sep 12, 2025
6ab5765
Merge branch 'feat/js-peer-workshop' of https://github.com/Nkovaturie…
Hany-Almnaem Sep 12, 2025
064185d
Revert "Merge branch 'feat/js-peer-workshop' of https://github.com/Nk…
Hany-Almnaem Sep 12, 2025
09a395f
feat: add JavaScript Lesson 6 - GossipSub Pub/Sub (#14)
Hany-Almnaem Sep 14, 2025
d34fa95
feat: enhance GossipSub lesson with multi-peer demonstration (#15)
Hany-Almnaem Sep 21, 2025
4ac93ae
add lesson 07: kad-dht
Oct 19, 2025
5f76876
add lesson-08:final checkpoint
Oct 21, 2025
86f103a
feat(lesson-08):fix gossipsub mesh and add interactive checker server
Oct 23, 2025
3e8cd05
Merge branch 'libp2p:main' into main
Nkovaturient Oct 30, 2025
c172b5b
Merge branch 'libp2p:main' into feat/js-peer-workshop
Nkovaturient Oct 30, 2025
d3a60dd
fix merge conflicts
Oct 30, 2025
b6079bf
feat(js-peer): refactor lessons, implement unified checker, interacti…
Nov 2, 2025
cf77a27
merge: complete merge with resolved conflicts
Nov 2, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions en/js/01-identity-and-swarm/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:20-alpine as build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .

FROM node:20-alpine
WORKDIR /usr/src/app
COPY --from=build /usr/src/app /usr/src/app
CMD ["node", "index.js"]
24 changes: 24 additions & 0 deletions en/js/01-identity-and-swarm/app/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { createLibp2p } from 'libp2p';
import { tcp } from '@libp2p/tcp';
import { noise } from '@chainsafe/libp2p-noise';
import { yamux } from '@chainsafe/libp2p-yamux';

const main = async () => {
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [tcp()],
connectionEncrypters: [noise()],
streamMuxers: [yamux()]
});

await node.start();
console.log('PeerId:', node.peerId.toString());
console.log('Listening on:');
node.getMultiaddrs().forEach((addr) => {
console.log(addr.toString());
});
};

main().catch(console.error);
17 changes: 17 additions & 0 deletions en/js/01-identity-and-swarm/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import sys
import re

SUCCESS = '\u2705' # ✅
FAILURE = '\u274C' # ❌

output = sys.stdin.read()

peerid_match = re.search(r'PeerId: ([A-Za-z0-9]+)', output)
listening_match = re.search(r'Listening on:\n(.+)', output, re.DOTALL)

if peerid_match and listening_match and len(listening_match.group(1).strip().split('\n')) >= 1:
print(SUCCESS)
sys.exit(0)
else:
print(FAILURE)
sys.exit(1)
10 changes: 10 additions & 0 deletions en/js/01-identity-and-swarm/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: '3.8'
services:
app:
build: ./app
command: node index.js
working_dir: /usr/src/app
volumes:
- ./app:/usr/src/app
environment:
- NODE_ENV=development
80 changes: 80 additions & 0 deletions en/js/01-identity-and-swarm/lesson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Lesson 1: Identity & Swarm Basics

Welcome to your first step in building a universal connectivity app with js-libp2p!

## Objective
- Generate a PeerId
- Set up a minimal js-libp2p node with TCP transport
- Print your PeerId and listening addresses
- Observe basic node events

---

## Step-by-Step Instructions

1. **Install Dependencies**
```sh
npm install libp2p @libp2p/tcp @chainsafe/libp2p-noise @chainsafe/libp2p-yamux
```

2. **Generate a PeerId and Set Up Node**
- Create `index.js` in your `app/` directory.
- Use the following template to get started:

```js
import { createLibp2p } from 'libp2p';
import { tcp } from '@libp2p/tcp';
import { noise } from '@chainsafe/libp2p-noise';
import { yamux } from '@chainsafe/libp2p-yamux';

const main = async () => {
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [tcp()],
connectionEncrypters: [noise()],
streamMuxers: [yamux()]
});

await node.start();
console.log('PeerId:', node.peerId.toString());
console.log('Listening on:');
node.getMultiaddrs().forEach((addr) => {
console.log(addr.toString());
});
};

main().catch(console.error);
```

3. **Run Your Node**
```sh
node app/index.js
```
- You should see your PeerId and at least one listening address printed.

---

## Hints

<details>
<summary>Hint 1: How do I generate a PeerId?</summary>
PeerId is generated automatically when you create a libp2p node with `createLibp2p`.
</details>

<details>
<summary>Hint 2: What should I print?</summary>
Print your PeerId using `node.peerId.toString()` and each address from `node.getMultiaddrs()`.
</details>

<details>
<summary>Hint 3: Full Solution</summary>
See the code template above. Make sure to install all dependencies and run the script from the correct directory.
</details>

---

## Resources
- [js-libp2p Getting Started Guide](https://docs.libp2p.io/guides/getting-started/javascript)
- [js-libp2p API Docs](https://libp2p.github.io/js-libp2p/)
17 changes: 17 additions & 0 deletions en/js/01-identity-and-swarm/lesson.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: Identity & Swarm Basics
slug: identity-and-swarm
language: javascript
difficulty: beginner
description: |
Learn how to generate a PeerId, set up a basic js-libp2p node, and print your PeerId and listening addresses.
objectives:
- Generate a PeerId using js-libp2p
- Set up a minimal libp2p node with TCP transport
- Print PeerId and listening addresses
- Observe basic node events
validation:
method: output
success_regex: 'PeerId: [A-Za-z0-9]+\nListening on: .+'
failure_message: 'Output must include a valid PeerId and at least one listening address.'
emoji_success: '\u2705' # ✅
emoji_failure: '\u274C' # ❌
10 changes: 10 additions & 0 deletions en/js/02-tcp-transport/app/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
FROM node:20-alpine as build
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .

FROM node:20-alpine
WORKDIR /usr/src/app
COPY --from=build /usr/src/app /usr/src/app
CMD ["node", "index.js"]
10 changes: 10 additions & 0 deletions en/js/02-tcp-transport/app/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
version: '3.8'
services:
app:
build: ./app
command: node index.js
working_dir: /usr/src/app
volumes:
- ./app:/usr/src/app
environment:
- NODE_ENV=development
16 changes: 16 additions & 0 deletions en/js/02-tcp-transport/check.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import sys
import re

SUCCESS = '\u2705'
FAILURE = '\u274C'

output = sys.stdin.read()

multiaddr_match = re.search(r'Listening on:.*(/ip4/.+/tcp/\d+/p2p/[A-Za-z0-9]+)', output, re.DOTALL)

if multiaddr_match:
print(SUCCESS)
sys.exit(0)
else:
print(FAILURE)
sys.exit(1)
40 changes: 40 additions & 0 deletions en/js/02-tcp-transport/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { createLibp2p } from 'libp2p';
import { tcp } from '@libp2p/tcp';
import { noise } from '@chainsafe/libp2p-noise';
import { yamux } from '@chainsafe/libp2p-yamux';

const main = async () => {
try {
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [tcp()],
connectionEncrypters: [noise()],
streamMuxers: [yamux()]
});

node.addEventListener('peer:connect', (evt) => {
console.log('Connected to:', evt.detail.remotePeer.toString());
});

node.addEventListener('peer:disconnect', (evt) => {
console.log('Disconnected from:', evt.detail.remotePeer.toString());
});

node.addEventListener('error', (evt) => {
console.error('Node error:', evt.detail);
});

await node.start();
console.log('Listening on:');
node.getMultiaddrs().forEach((addr) => {
console.log(addr.toString());
});
} catch (err) {
console.error('Failed to start libp2p node:', err);
process.exit(1);
}
};

main();
97 changes: 97 additions & 0 deletions en/js/02-tcp-transport/lesson.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# Lesson 2: TCP Transport

Welcome to Lesson 2! In this lesson, you'll set up TCP transport with Noise encryption and Yamux multiplexing in js-libp2p. You'll also learn to handle connection events and errors robustly.

## Objective
- Add TCP transport to your libp2p node
- Add Noise encryption and Yamux multiplexing
- Listen on a TCP address and print it
- Handle connection and error events

---

## Step-by-Step Instructions

1. **Install Dependencies**
(If you haven't already, run:)
```sh
npm install libp2p @libp2p/tcp @chainsafe/libp2p-noise @chainsafe/libp2p-yamux
```

2. **Update Your Node Setup**
- In your `app/` directory, update or create `index.js` as follows:

```js
import { createLibp2p } from 'libp2p';
import { tcp } from '@libp2p/tcp';
import { noise } from '@chainsafe/libp2p-noise';
import { yamux } from '@chainsafe/libp2p-yamux';

const main = async () => {
try {
const node = await createLibp2p({
addresses: {
listen: ['/ip4/0.0.0.0/tcp/0']
},
transports: [tcp()],
connectionEncrypters: [noise()],
streamMuxers: [yamux()]
});

node.addEventListener('peer:connect', (evt) => {
console.log('Connected to:', evt.detail.remotePeer.toString());
});

node.addEventListener('peer:disconnect', (evt) => {
console.log('Disconnected from:', evt.detail.remotePeer.toString());
});

node.addEventListener('error', (evt) => {
console.error('Node error:', evt.detail);
});

await node.start();
console.log('Listening on:');
node.getMultiaddrs().forEach((addr) => {
console.log(addr.toString());
});
} catch (err) {
console.error('Failed to start libp2p node:', err);
process.exit(1);
}
};

main();
```

3. **Run Your Node**
```sh
node app/index.js
```
- You should see at least one valid TCP multiaddr printed.
- Try connecting/disconnecting peers to see event logs (in later lessons).

---

## Hints

<details>
<summary>Hint 1: How do I handle connection events?</summary>
Use `node.addEventListener('peer:connect', handler)` and similar for disconnects.
</details>

<details>
<summary>Hint 2: How do I handle errors?</summary>
Wrap your async code in try/catch and listen for the 'error' event on the node.
</details>

<details>
<summary>Hint 3: Full Solution</summary>
See the code template above. Ensure you handle errors and print all listening addresses.
</details>

---

## Resources
- [js-libp2p Getting Started Guide](https://docs.libp2p.io/guides/getting-started/javascript)
- [js-libp2p API Docs](https://libp2p.github.io/js-libp2p/)
17 changes: 17 additions & 0 deletions en/js/02-tcp-transport/lesson.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
title: TCP Transport
slug: tcp-transport
language: javascript
difficulty: beginner
description: |
Set up TCP transport with Noise encryption and Yamux multiplexing in js-libp2p. Learn to handle connection events and errors robustly.
objectives:
- Add TCP transport to your libp2p node
- Add Noise encryption and Yamux multiplexing
- Listen on a TCP address and print it
- Handle connection and error events
validation:
method: output
success_regex: 'Listening on: /ip4/.+/tcp/\d+/p2p/[A-Za-z0-9]+'
failure_message: 'Output must include at least one valid TCP multiaddr.'
emoji_success: '\u2705' # ✅
emoji_failure: '\u274C' # ❌
Loading