@@ -68,6 +68,18 @@ export type CreateInstanceOptions = (SimpleLibp2pOptions | Libp2pOptions) & {
6868 indexer ?: ( directory ?: string ) => Promise < Indices > | Indices ;
6969} & OptionalCreateOptions ;
7070
71+ export type DialReadiness =
72+ | "connection"
73+ | "services"
74+ | "services-and-fanout" ;
75+
76+ export type DialOptions = {
77+ dialTimeoutMs ?: number ;
78+ serviceWaitTimeoutMs ?: number ;
79+ readiness ?: DialReadiness ;
80+ signal ?: AbortSignal ;
81+ } ;
82+
7183const isLibp2pInstance = ( libp2p : Libp2pExtended | ClientCreateOptions ) =>
7284 ! ! ( libp2p as Libp2p ) . getMultiaddrs ;
7385
@@ -411,7 +423,7 @@ export class Peerbit implements ProgramClient {
411423 */
412424 async dial (
413425 address : string | Multiaddr | Multiaddr [ ] | ProgramClient ,
414- options ?: { dialTimeoutMs ?: number ; signal ?: AbortSignal } ,
426+ options ?: DialOptions ,
415427 ) : Promise < boolean > {
416428 const maddress =
417429 typeof address === "string"
@@ -457,21 +469,42 @@ export class Peerbit implements ProgramClient {
457469 const publicKey = Ed25519PublicKey . fromPeerId ( connection . remotePeer ) ;
458470 const peerHash = publicKey . hashcode ( ) ;
459471
460- // TODO, do this as a promise instead using the onPeerConnected vents in pubsub and blocks
461- try {
462- await this . libp2p . services . pubsub . waitFor ( peerHash , {
463- target : "neighbor" ,
464- } ) ;
465- } catch ( error ) {
466- throw new Error ( `Failed to dial peer. Not available on Pubsub` ) ;
472+ const resolvedReadiness : DialReadiness =
473+ options ?. readiness ??
474+ ( this . libp2p . services . fanout ? "services-and-fanout" : "services" ) ;
475+ const serviceWaitTimeoutMs =
476+ options ?. serviceWaitTimeoutMs ?? options ?. dialTimeoutMs ;
477+ if ( resolvedReadiness === "connection" ) {
478+ return true ;
467479 }
468480
469- try {
470- await this . libp2p . services . blocks . waitFor ( peerHash , {
471- target : "neighbor" ,
472- } ) ;
473- } catch ( error ) {
474- throw new Error ( `Failed to dial peer. Not available on Blocks` ) ;
481+ const waitForNeighbor = async (
482+ label : "Pubsub" | "Blocks" | "Fanout" ,
483+ service : { waitFor : ( peer : string , options ?: any ) => Promise < any > } ,
484+ ) => {
485+ try {
486+ await service . waitFor ( peerHash , {
487+ target : "neighbor" ,
488+ timeout : serviceWaitTimeoutMs ,
489+ signal : dialSignal ,
490+ } ) ;
491+ } catch ( _error ) {
492+ throw new Error ( `Failed to dial peer. Not available on ${ label } ` ) ;
493+ }
494+ } ;
495+
496+ // TODO, do this as a promise instead using the onPeerConnected vents in pubsub and blocks
497+ await waitForNeighbor ( "Pubsub" , this . libp2p . services . pubsub ) ;
498+ await waitForNeighbor ( "Blocks" , this . libp2p . services . blocks ) ;
499+
500+ if ( resolvedReadiness === "services-and-fanout" ) {
501+ const fanoutService = ( this . libp2p . services as any ) . fanout ;
502+ if ( ! fanoutService ?. waitFor ) {
503+ throw new Error (
504+ "Failed to dial peer. Not available on Fanout (service missing)" ,
505+ ) ;
506+ }
507+ await waitForNeighbor ( "Fanout" , fanoutService ) ;
475508 }
476509
477510 return true ;
0 commit comments