1- import {
2- createDelegatedRoutingV1HttpApiClient ,
3- DelegatedRoutingV1HttpApiClient ,
4- } from '@helia/delegated-routing-v1-http-api-client'
51import { createLibp2p } from 'libp2p'
2+ import { bootstrap } from '@libp2p/bootstrap'
63import { identify } from '@libp2p/identify'
7- import { peerIdFromString } from '@libp2p/peer-id'
84import { noise } from '@chainsafe/libp2p-noise'
95import { yamux } from '@chainsafe/libp2p-yamux'
106import { Multiaddr } from '@multiformats/multiaddr'
117import { sha256 } from 'multiformats/hashes/sha2'
12- import type { Connection , Message , SignedMessage , PeerId , Libp2p } from '@libp2p/interface'
8+ import type { Connection , Message , SignedMessage , Libp2p } from '@libp2p/interface'
139import { gossipsub } from '@chainsafe/libp2p-gossipsub'
1410import { webSockets } from '@libp2p/websockets'
1511import { webTransport } from '@libp2p/webtransport'
1612import { webRTC , webRTCDirect } from '@libp2p/webrtc'
1713import { circuitRelayTransport } from '@libp2p/circuit-relay-v2'
1814import { pubsubPeerDiscovery } from '@libp2p/pubsub-peer-discovery'
1915import { ping } from '@libp2p/ping'
20- import { BOOTSTRAP_PEER_IDS , CHAT_FILE_TOPIC , CHAT_TOPIC , PUBSUB_PEER_DISCOVERY } from './constants'
21- import first from 'it-first'
16+ import { BOOTSTRAP_MULTIADDRS , CHAT_FILE_TOPIC , CHAT_TOPIC , PUBSUB_PEER_DISCOVERY } from './constants'
2217import { forComponent , enable } from './logger'
2318import { directMessage } from './direct-message'
2419import type { Libp2pType } from '@/context/ctx'
@@ -29,10 +24,7 @@ export async function startLibp2p(): Promise<Libp2pType> {
2924 // enable verbose logging in browser console to view debug logs
3025 enable ( 'ui*,libp2p*,-libp2p:connection-manager*,-*:trace' )
3126
32- const delegatedClient = createDelegatedRoutingV1HttpApiClient ( 'https://delegated-ipfs.dev' )
33-
34- const relayListenAddrs = await getRelayListenAddrs ( delegatedClient )
35- log ( 'starting libp2p with relayListenAddrs: %o' , relayListenAddrs )
27+ log ( 'starting libp2p with bootstrap multiaddrs: %o' , BOOTSTRAP_MULTIADDRS )
3628
3729 let libp2p : Libp2pType
3830
@@ -41,7 +33,6 @@ export async function startLibp2p(): Promise<Libp2pType> {
4133 listen : [
4234 // 👇 Listen for webRTC connection
4335 '/webrtc' ,
44- ...relayListenAddrs ,
4536 ] ,
4637 } ,
4738 transports : [
@@ -59,6 +50,11 @@ export async function startLibp2p(): Promise<Libp2pType> {
5950 denyDialMultiaddr : async ( ) => false ,
6051 } ,
6152 peerDiscovery : [
53+ bootstrap ( {
54+ list : [ ...BOOTSTRAP_MULTIADDRS ] ,
55+ timeout : 10_000 ,
56+ tagName : 'uc-bootstrap' ,
57+ } ) ,
6258 pubsubPeerDiscovery ( {
6359 interval : 10_000 ,
6460 topics : [ PUBSUB_PEER_DISCOVERY ] ,
@@ -71,9 +67,6 @@ export async function startLibp2p(): Promise<Libp2pType> {
7167 msgIdFn : msgIdFnStrictNoSign ,
7268 ignoreDuplicatePublishError : true ,
7369 } ) ,
74- // Delegated routing helps us discover the ephemeral multiaddrs of the dedicated go and rust bootstrap peers
75- // This relies on the public delegated routing endpoint https://docs.ipfs.tech/concepts/public-utilities/#delegated-routing
76- delegatedRouting : ( ) => delegatedClient ,
7770 identify : identify ( ) ,
7871 // Custom protocol for direct messaging
7972 directMessage : directMessage ( ) ,
@@ -102,7 +95,13 @@ export async function startLibp2p(): Promise<Libp2pType> {
10295 return
10396 }
10497
105- dialWebRTCMaddrs ( libp2p , multiaddrs )
98+ // libp2p.dial() already deduplicates existing and in-flight connection attempts
99+ // for the same peer and can try multiple candidate multiaddrs until one succeeds.
100+ log ( `dialling discovered multiaddrs: %o` , multiaddrs )
101+
102+ void libp2p . dial ( multiaddrs ) . catch ( ( error ) => {
103+ log . error ( `failed to dial discovered multiaddrs for peer %s: %o` , id , error )
104+ } )
106105 } )
107106
108107 return libp2p
@@ -119,23 +118,6 @@ export async function msgIdFnStrictNoSign(msg: Message): Promise<Uint8Array> {
119118 return await sha256 . encode ( encodedSeqNum )
120119}
121120
122- // Function which dials one maddr at a time to avoid establishing multiple connections to the same peer
123- async function dialWebRTCMaddrs ( libp2p : Libp2p , multiaddrs : Multiaddr [ ] ) : Promise < void > {
124- // Filter webrtc (browser-to-browser) multiaddrs
125- const webRTCMadrs = multiaddrs . filter ( ( maddr ) => maddr . protoNames ( ) . includes ( 'webrtc' ) )
126- log ( `dialling WebRTC multiaddrs: %o` , webRTCMadrs )
127-
128- for ( const addr of webRTCMadrs ) {
129- try {
130- log ( `attempting to dial webrtc multiaddr: %o` , addr )
131- await libp2p . dial ( addr )
132- return // if we succeed dialing the peer, no need to try another address
133- } catch ( error ) {
134- log . error ( `failed to dial webrtc multiaddr: %o` , addr )
135- }
136- }
137- }
138-
139121export const connectToMultiaddr = ( libp2p : Libp2p ) => async ( multiaddr : Multiaddr ) => {
140122 log ( `dialling: %a` , multiaddr )
141123 try {
@@ -148,32 +130,6 @@ export const connectToMultiaddr = (libp2p: Libp2p) => async (multiaddr: Multiadd
148130 }
149131}
150132
151- // Function which resolves PeerIDs of rust/go bootstrap nodes to multiaddrs dialable from the browser
152- // Returns both the dialable multiaddrs in addition to the relay
153- async function getRelayListenAddrs ( client : DelegatedRoutingV1HttpApiClient ) : Promise < string [ ] > {
154- const peers = await Promise . all ( BOOTSTRAP_PEER_IDS . map ( ( peerId ) => first ( client . getPeers ( peerIdFromString ( peerId ) ) ) ) )
155-
156- const relayListenAddrs = [ ]
157- for ( const p of peers ) {
158- if ( p && p . Addrs . length > 0 ) {
159- for ( const maddr of p . Addrs ) {
160- const protos = maddr . protoNames ( )
161- // Note: narrowing to Secure WebSockets and IP4 addresses to avoid potential issues with ipv6
162- // https://github.com/libp2p/js-libp2p/issues/2977
163- if ( protos . includes ( 'tls' ) && protos . includes ( 'ws' ) ) {
164- if ( maddr . nodeAddress ( ) . address === '127.0.0.1' ) continue // skip loopback
165- relayListenAddrs . push ( getRelayListenAddr ( maddr , p . ID ) )
166- }
167- }
168- }
169- }
170- return relayListenAddrs
171- }
172-
173- // Constructs a multiaddr string representing the circuit relay v2 listen address for a relayed connection to the given peer.
174- const getRelayListenAddr = ( maddr : Multiaddr , peer : PeerId ) : string =>
175- `${ maddr . toString ( ) } /p2p/${ peer . toString ( ) } /p2p-circuit`
176-
177133export const getFormattedConnections = ( connections : Connection [ ] ) =>
178134 connections . map ( ( conn ) => ( {
179135 peerId : conn . remotePeer ,
0 commit comments