1
1
import { IDBDatastore } from 'datastore-idb'
2
- import { createDelegatedRoutingV1HttpApiClient } from '@helia/delegated-routing-v1-http-api-client'
2
+ import {
3
+ createDelegatedRoutingV1HttpApiClient ,
4
+ DelegatedRoutingV1HttpApiClient ,
5
+ } from '@helia/delegated-routing-v1-http-api-client'
3
6
import { createLibp2p , Libp2p } from 'libp2p'
4
7
import { identify } from '@libp2p/identify'
5
- import { peerIdFromString } from '@libp2p/peer-id'
8
+ import { peerIdFromString } from '@libp2p/peer-id'
6
9
import { noise } from '@chainsafe/libp2p-noise'
7
10
import { yamux } from '@chainsafe/libp2p-yamux'
8
11
import { bootstrap } from '@libp2p/bootstrap'
@@ -13,9 +16,16 @@ import { gossipsub } from '@chainsafe/libp2p-gossipsub'
13
16
import { webSockets } from '@libp2p/websockets'
14
17
import { webTransport } from '@libp2p/webtransport'
15
18
import { webRTC , webRTCDirect } from '@libp2p/webrtc'
16
- import { CHAT_FILE_TOPIC , CHAT_TOPIC , WEBRTC_BOOTSTRAP_PEER_ID , WEBTRANSPORT_BOOTSTRAP_PEER_ID } from './constants'
17
- import * as filters from "@libp2p/websockets/filters"
19
+ import {
20
+ CHAT_FILE_TOPIC ,
21
+ CHAT_TOPIC ,
22
+ WEBRTC_BOOTSTRAP_PEER_ID ,
23
+ WEBTRANSPORT_BOOTSTRAP_PEER_ID ,
24
+ } from './constants'
25
+
26
+ import * as filters from '@libp2p/websockets/filters'
18
27
import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
28
+ import first from 'it-first'
19
29
20
30
export async function startLibp2p ( ) {
21
31
// enable verbose logging in browser console to view debug logs
@@ -26,38 +36,43 @@ export async function startLibp2p() {
26
36
27
37
await datastore . open ( )
28
38
39
+ const delegatedClient = createDelegatedRoutingV1HttpApiClient ( 'https://delegated-ipfs.dev' )
40
+ const { bootstrapAddrs, listenAddrs } = await getBootstrapMultiaddrs ( delegatedClient )
41
+ console . log ( bootstrapAddrs , listenAddrs )
42
+
43
+
29
44
const libp2p = await createLibp2p ( {
30
45
datastore,
31
46
addresses : {
32
47
listen : [
33
48
// 👇 Listen for webRTC connection
34
- '/webrtc'
35
- ]
49
+ '/webrtc' ,
50
+ ...listenAddrs ,
51
+ ] ,
36
52
} ,
37
53
transports : [
38
54
webTransport ( ) ,
39
55
webSockets ( ) ,
40
56
webRTC ( {
41
57
rtcConfiguration : {
42
- iceServers : [ {
43
- // STUN servers help the browser discover its own public IPs
44
- urls : [
45
- 'stun:stun.l.google.com:19302' ,
46
- 'stun:global.stun.twilio.com:3478'
47
- ]
48
- } ]
49
- }
58
+ iceServers : [
59
+ {
60
+ // STUN servers help the browser discover its own public IPs
61
+ urls : [ 'stun:stun.l.google.com:19302' , 'stun:global.stun.twilio.com:3478' ] ,
62
+ } ,
63
+ ] ,
64
+ } ,
50
65
} ) ,
51
66
webRTCDirect ( ) ,
52
67
// 👇 Required to create circuit relay reservations in order to hole punch browser-to-browser WebRTC connections
53
68
circuitRelayTransport ( {
54
69
// When set to >0, this will look up the magic CID in order to discover circuit relay peers it can create a reservation with
55
- discoverRelays : 1 ,
56
- } )
70
+ discoverRelays : 0 ,
71
+ } ) ,
57
72
] ,
58
73
connectionManager : {
59
74
maxConnections : 10 ,
60
- minConnections : 3
75
+ minConnections : 3 ,
61
76
} ,
62
77
connectionEncryption : [ noise ( ) ] ,
63
78
streamMuxers : [ yamux ( ) ] ,
@@ -66,18 +81,21 @@ export async function startLibp2p() {
66
81
} ,
67
82
// The app-specific go and rust peers use WebTransport and WebRTC-direct which have ephemeral multiadrrs that change.
68
83
// Thus, we dial them using only their peer id below, with delegated routing to discovery their multiaddrs
69
- // peerDiscovery: [
70
- // bootstrap({
71
- // list: [
72
- // '12D3KooWFhXabKDwALpzqMbto94sB7rvmZ6M28hs9Y9xSopDKwQr'
73
- // WEBRTC_BOOTSTRAP_NODE,
74
- // WEBTRANSPORT_BOOTSTRAP_NODE,
75
- // '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
76
- // '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa',
77
- // '/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
78
- // '/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt',
79
- // ],
80
- // }),
84
+ peerDiscovery : [
85
+ bootstrap ( {
86
+ list : bootstrapAddrs . map ( ( maddr ) => maddr . toString ( ) ) ,
87
+ } ) ,
88
+ ] ,
89
+ // [
90
+ // '12D3KooWFhXabKDwALpzqMbto94sB7rvmZ6M28hs9Y9xSopDKwQr'
91
+ // WEBRTC_BOOTSTRAP_NODE,
92
+ // WEBTRANSPORT_BOOTSTRAP_NODE,
93
+ // '/dnsaddr/bootstrap.libp2p.io/p2p/QmNnooDu7bfjPFoTZYxMNLWUQJyrVwtbZg5gBMjTezGAJN',
94
+ // '/dnsaddr/bootstrap.libp2p.io/p2p/QmQCU2EcMqAqQPR2i9bChDtGNJchTbq5TbXJJ16u19uLTa',
95
+ // '/dnsaddr/bootstrap.libp2p.io/p2p/QmbLHAnMoJPWSCR5Zhtx6BHJX9KiKNN6tpvbUcqanj75Nb',
96
+ // '/dnsaddr/bootstrap.libp2p.io/p2p/QmcZf59bWwK5XFi76CZX8cbJ4BhTzzA3gU1ZjYZcYW3dwt',
97
+ // ],
98
+ // }),
81
99
// ],
82
100
services : {
83
101
pubsub : gossipsub ( {
@@ -88,23 +106,19 @@ export async function startLibp2p() {
88
106
// Delegated routing helps us discover the ephemeral multiaddrs of the dedicated go and rust bootstrap peers
89
107
// This relies on the public delegated routing endpoint https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing
90
108
delegatedRouting : ( ) => createDelegatedRoutingV1HttpApiClient ( 'https://delegated-ipfs.dev' ) ,
91
- identify : identify ( )
109
+ identify : identify ( ) ,
92
110
} ,
93
111
} )
94
112
95
113
libp2p . services . pubsub . subscribe ( CHAT_TOPIC )
96
114
libp2p . services . pubsub . subscribe ( CHAT_FILE_TOPIC )
97
115
98
- // Try connecting to bootstrap ppers
99
- Promise . all ( [
100
- libp2p . dial ( peerIdFromString ( WEBRTC_BOOTSTRAP_PEER_ID ) ) ,
101
- libp2p . dial ( peerIdFromString ( WEBTRANSPORT_BOOTSTRAP_PEER_ID ) )
102
- ] )
103
- . catch ( e => { console . log ( 'woot' , e ) } )
116
+ // .catch((e) => {
117
+ // console.log('woot', e)
118
+ // })
104
119
105
120
libp2p . addEventListener ( 'self:peer:update' , ( { detail : { peer } } ) => {
106
121
const multiaddrs = peer . addresses . map ( ( { multiaddr } ) => multiaddr )
107
-
108
122
console . log ( `changed multiaddrs: peer ${ peer . id . toString ( ) } multiaddrs: ${ multiaddrs } ` )
109
123
} )
110
124
@@ -115,24 +129,45 @@ export async function startLibp2p() {
115
129
// every agent in network should use the same message id function
116
130
// messages could be perceived as duplicate if this isnt added (as opposed to rust peer which has unique message ids)
117
131
export async function msgIdFnStrictNoSign ( msg : Message ) : Promise < Uint8Array > {
118
- var enc = new TextEncoder ( ) ;
132
+ var enc = new TextEncoder ( )
119
133
120
134
const signedMessage = msg as SignedMessage
121
- const encodedSeqNum = enc . encode ( signedMessage . sequenceNumber . toString ( ) ) ;
135
+ const encodedSeqNum = enc . encode ( signedMessage . sequenceNumber . toString ( ) )
122
136
return await sha256 . encode ( encodedSeqNum )
123
137
}
124
138
139
+ export const connectToMultiaddr = ( libp2p : Libp2p ) => async ( multiaddr : Multiaddr ) => {
140
+ console . log ( `dialling: ${ multiaddr . toString ( ) } ` )
141
+ try {
142
+ const conn = await libp2p . dial ( multiaddr )
143
+ console . info ( 'connected to' , conn . remotePeer , 'on' , conn . remoteAddr )
144
+ return conn
145
+ } catch ( e ) {
146
+ console . error ( e )
147
+ throw e
148
+ }
149
+ }
125
150
126
- export const connectToMultiaddr =
127
- ( libp2p : Libp2p ) => async ( multiaddr : Multiaddr ) => {
128
- console . log ( `dialling: ${ multiaddr . toString ( ) } ` )
129
- try {
130
- const conn = await libp2p . dial ( multiaddr )
131
- console . info ( 'connected to' , conn . remotePeer , 'on' , conn . remoteAddr )
132
- return conn
133
- } catch ( e ) {
134
- console . error ( e )
135
- throw e
151
+ const getBootstrapMultiaddrs = async ( client : DelegatedRoutingV1HttpApiClient ) => {
152
+ const peers = await Promise . all ( [
153
+ first ( client . getPeers ( peerIdFromString ( WEBTRANSPORT_BOOTSTRAP_PEER_ID ) ) ) ,
154
+ first ( client . getPeers ( peerIdFromString ( WEBRTC_BOOTSTRAP_PEER_ID ) ) ) ,
155
+ ] )
156
+ const bootstrapAddrs = [ ]
157
+ const listenAddrs = [ ]
158
+ for ( const p of peers ) {
159
+ if ( p && p . Addrs . length > 0 ) {
160
+ for ( const maddr of p . Addrs ) {
161
+ const protos = maddr . protoNames ( )
162
+ if (
163
+ ( protos . includes ( 'webtransport' ) || protos . includes ( 'webrtc-direct' ) ) &&
164
+ protos . includes ( 'certhash' )
165
+ ) {
166
+ bootstrapAddrs . push ( maddr )
167
+ listenAddrs . push ( `${ maddr . toString ( ) } /p2p/${ p . ID . toString ( ) } /p2p-circuit` )
168
+ }
169
+ }
136
170
}
137
171
}
138
-
172
+ return { bootstrapAddrs, listenAddrs }
173
+ }
0 commit comments