12
12
* ```
13
13
*/
14
14
15
- import { CodeError } from '@libp2p/interface/errors'
16
- import { base58btc } from 'multiformats/bases/base58'
17
- import { CID } from 'multiformats/cid'
18
- import { equals as uint8ArrayEquals } from 'uint8arrays/equals'
19
- import { toString as uint8ArrayToString } from 'uint8arrays/to-string'
20
- import { bytesToMultiaddrParts , stringToMultiaddrParts , type MultiaddrParts , tuplesToBytes } from './codec.js'
21
- import { getProtocol , names } from './protocols-table.js'
22
-
23
- const inspect = Symbol . for ( 'nodejs.util.inspect.custom' )
24
-
25
- const DNS_CODES = [
26
- getProtocol ( 'dns' ) . code ,
27
- getProtocol ( 'dns4' ) . code ,
28
- getProtocol ( 'dns6' ) . code ,
29
- getProtocol ( 'dnsaddr' ) . code
30
- ]
15
+ import { Multiaddr as MultiaddrClass , symbol } from './multiaddr.js'
16
+ import { getProtocol } from './protocols-table.js'
31
17
32
18
/**
33
19
* Protocols are present in the protocol table
@@ -91,7 +77,6 @@ export interface AbortOptions {
91
77
* All configured {@link Resolver}s
92
78
*/
93
79
export const resolvers = new Map < string , Resolver > ( )
94
- const symbol = Symbol . for ( '@multiformats/js-multiaddr/multiaddr' )
95
80
96
81
export { MultiaddrFilter } from './filter/multiaddr-filter.js'
97
82
@@ -444,7 +429,7 @@ export function fromNodeAddress (addr: NodeAddress, transport: string): Multiadd
444
429
default :
445
430
throw Error ( 'Invalid addr family, should be 4 or 6.' )
446
431
}
447
- return new DefaultMultiaddr ( '/' + [ ip , host , transport , addr . port ] . join ( '/' ) )
432
+ return new MultiaddrClass ( '/' + [ ip , host , transport , addr . port ] . join ( '/' ) )
448
433
}
449
434
450
435
/**
@@ -488,260 +473,6 @@ export function isMultiaddr (value: any): value is Multiaddr {
488
473
return Boolean ( value ?. [ symbol ] )
489
474
}
490
475
491
- /**
492
- * Creates a {@link Multiaddr} from a {@link MultiaddrInput}
493
- */
494
- class DefaultMultiaddr implements Multiaddr {
495
- public bytes : Uint8Array
496
- #string: string
497
- #tuples: Tuple [ ]
498
- #stringTuples: StringTuple [ ]
499
- #path: string | null
500
-
501
- [ symbol ] : boolean = true
502
-
503
- constructor ( addr ?: MultiaddrInput ) {
504
- // default
505
- if ( addr == null ) {
506
- addr = ''
507
- }
508
-
509
- let parts : MultiaddrParts
510
- if ( addr instanceof Uint8Array ) {
511
- parts = bytesToMultiaddrParts ( addr )
512
- } else if ( typeof addr === 'string' ) {
513
- if ( addr . length > 0 && addr . charAt ( 0 ) !== '/' ) {
514
- throw new Error ( `multiaddr "${ addr } " must start with a "/"` )
515
- }
516
- parts = stringToMultiaddrParts ( addr )
517
- } else if ( isMultiaddr ( addr ) ) { // Multiaddr
518
- parts = bytesToMultiaddrParts ( addr . bytes )
519
- } else {
520
- throw new Error ( 'addr must be a string, Buffer, or another Multiaddr' )
521
- }
522
-
523
- this . bytes = parts . bytes
524
- this . #string = parts . string
525
- this . #tuples = parts . tuples
526
- this . #stringTuples = parts . stringTuples
527
- this . #path = parts . path
528
- }
529
-
530
- toString ( ) : string {
531
- return this . #string
532
- }
533
-
534
- toJSON ( ) : string {
535
- return this . toString ( )
536
- }
537
-
538
- toOptions ( ) : MultiaddrObject {
539
- let family : 4 | 6 | undefined
540
- let transport : string | undefined
541
- let host : string | undefined
542
- let port : number | undefined
543
- let zone = ''
544
-
545
- const tcp = getProtocol ( 'tcp' )
546
- const udp = getProtocol ( 'udp' )
547
- const ip4 = getProtocol ( 'ip4' )
548
- const ip6 = getProtocol ( 'ip6' )
549
- const dns6 = getProtocol ( 'dns6' )
550
- const ip6zone = getProtocol ( 'ip6zone' )
551
-
552
- for ( const [ code , value ] of this . stringTuples ( ) ) {
553
- if ( code === ip6zone . code ) {
554
- zone = `%${ value ?? '' } `
555
- }
556
-
557
- // default to https when protocol & port are omitted from DNS addrs
558
- if ( DNS_CODES . includes ( code ) ) {
559
- transport = tcp . name
560
- port = 443
561
- host = `${ value ?? '' } ${ zone } `
562
- family = code === dns6 . code ? 6 : 4
563
- }
564
-
565
- if ( code === tcp . code || code === udp . code ) {
566
- transport = getProtocol ( code ) . name
567
- port = parseInt ( value ?? '' )
568
- }
569
-
570
- if ( code === ip4 . code || code === ip6 . code ) {
571
- transport = getProtocol ( code ) . name
572
- host = `${ value ?? '' } ${ zone } `
573
- family = code === ip6 . code ? 6 : 4
574
- }
575
- }
576
-
577
- if ( family == null || transport == null || host == null || port == null ) {
578
- throw new Error ( 'multiaddr must have a valid format: "/{ip4, ip6, dns4, dns6, dnsaddr}/{address}/{tcp, udp}/{port}".' )
579
- }
580
-
581
- const opts : MultiaddrObject = {
582
- family,
583
- host,
584
- transport,
585
- port
586
- }
587
-
588
- return opts
589
- }
590
-
591
- protos ( ) : Protocol [ ] {
592
- return this . #tuples. map ( ( [ code ] ) => Object . assign ( { } , getProtocol ( code ) ) )
593
- }
594
-
595
- protoCodes ( ) : number [ ] {
596
- return this . #tuples. map ( ( [ code ] ) => code )
597
- }
598
-
599
- protoNames ( ) : string [ ] {
600
- return this . #tuples. map ( ( [ code ] ) => getProtocol ( code ) . name )
601
- }
602
-
603
- tuples ( ) : Array < [ number , Uint8Array ?] > {
604
- return this . #tuples
605
- }
606
-
607
- stringTuples ( ) : Array < [ number , string ?] > {
608
- return this . #stringTuples
609
- }
610
-
611
- encapsulate ( addr : MultiaddrInput ) : Multiaddr {
612
- addr = new DefaultMultiaddr ( addr )
613
- return new DefaultMultiaddr ( this . toString ( ) + addr . toString ( ) )
614
- }
615
-
616
- decapsulate ( addr : Multiaddr | string ) : Multiaddr {
617
- const addrString = addr . toString ( )
618
- const s = this . toString ( )
619
- const i = s . lastIndexOf ( addrString )
620
- if ( i < 0 ) {
621
- throw new Error ( `Address ${ this . toString ( ) } does not contain subaddress: ${ addr . toString ( ) } ` )
622
- }
623
- return new DefaultMultiaddr ( s . slice ( 0 , i ) )
624
- }
625
-
626
- decapsulateCode ( code : number ) : Multiaddr {
627
- const tuples = this . tuples ( )
628
- for ( let i = tuples . length - 1 ; i >= 0 ; i -- ) {
629
- if ( tuples [ i ] [ 0 ] === code ) {
630
- return new DefaultMultiaddr ( tuplesToBytes ( tuples . slice ( 0 , i ) ) )
631
- }
632
- }
633
- return this
634
- }
635
-
636
- getPeerId ( ) : string | null {
637
- try {
638
- let tuples : Array < [ number , string | undefined ] > = [ ]
639
-
640
- this . stringTuples ( ) . forEach ( ( [ code , name ] ) => {
641
- if ( code === names . p2p . code ) {
642
- tuples . push ( [ code , name ] )
643
- }
644
-
645
- // if this is a p2p-circuit address, return the target peer id if present
646
- // not the peer id of the relay
647
- if ( code === names [ 'p2p-circuit' ] . code ) {
648
- tuples = [ ]
649
- }
650
- } )
651
-
652
- // Get the last ipfs tuple ['p2p', 'peerid string']
653
- const tuple = tuples . pop ( )
654
- if ( tuple ?. [ 1 ] != null ) {
655
- const peerIdStr = tuple [ 1 ]
656
-
657
- // peer id is base58btc encoded string but not multibase encoded so add the `z`
658
- // prefix so we can validate that it is correctly encoded
659
- if ( peerIdStr [ 0 ] === 'Q' || peerIdStr [ 0 ] === '1' ) {
660
- return uint8ArrayToString ( base58btc . decode ( `z${ peerIdStr } ` ) , 'base58btc' )
661
- }
662
-
663
- // try to parse peer id as CID
664
- return uint8ArrayToString ( CID . parse ( peerIdStr ) . multihash . bytes , 'base58btc' )
665
- }
666
-
667
- return null
668
- } catch ( e ) {
669
- return null
670
- }
671
- }
672
-
673
- getPath ( ) : string | null {
674
- return this . #path
675
- }
676
-
677
- equals ( addr : { bytes : Uint8Array } ) : boolean {
678
- return uint8ArrayEquals ( this . bytes , addr . bytes )
679
- }
680
-
681
- async resolve ( options ?: AbortOptions ) : Promise < Multiaddr [ ] > {
682
- const resolvableProto = this . protos ( ) . find ( ( p ) => p . resolvable )
683
-
684
- // Multiaddr is not resolvable?
685
- if ( resolvableProto == null ) {
686
- return [ this ]
687
- }
688
-
689
- const resolver = resolvers . get ( resolvableProto . name )
690
- if ( resolver == null ) {
691
- throw new CodeError ( `no available resolver for ${ resolvableProto . name } ` , 'ERR_NO_AVAILABLE_RESOLVER' )
692
- }
693
-
694
- const addresses = await resolver ( this , options )
695
- return addresses . map ( ( a ) => new DefaultMultiaddr ( a ) )
696
- }
697
-
698
- nodeAddress ( ) : NodeAddress {
699
- const options = this . toOptions ( )
700
-
701
- if ( options . transport !== 'tcp' && options . transport !== 'udp' ) {
702
- throw new Error ( `multiaddr must have a valid format - no protocol with name: "${ options . transport } ". Must have a valid transport protocol: "{tcp, udp}"` )
703
- }
704
-
705
- return {
706
- family : options . family ,
707
- address : options . host ,
708
- port : options . port
709
- }
710
- }
711
-
712
- isThinWaistAddress ( addr ?: Multiaddr ) : boolean {
713
- const protos = ( addr ?? this ) . protos ( )
714
-
715
- if ( protos . length !== 2 ) {
716
- return false
717
- }
718
-
719
- if ( protos [ 0 ] . code !== 4 && protos [ 0 ] . code !== 41 ) {
720
- return false
721
- }
722
- if ( protos [ 1 ] . code !== 6 && protos [ 1 ] . code !== 273 ) {
723
- return false
724
- }
725
- return true
726
- }
727
-
728
- /**
729
- * Returns Multiaddr as a human-readable string
730
- * https://nodejs.org/api/util.html#utilinspectcustom
731
- *
732
- * @example
733
- * ```js
734
- * import { multiaddr } from '@multiformats/multiaddr'
735
- *
736
- * console.info(multiaddr('/ip4/127.0.0.1/tcp/4001'))
737
- * // 'Multiaddr(/ip4/127.0.0.1/tcp/4001)'
738
- * ```
739
- */
740
- [ inspect ] ( ) : string {
741
- return `Multiaddr(${ this . #string} )`
742
- }
743
- }
744
-
745
476
/**
746
477
* A function that takes a {@link MultiaddrInput} and returns a {@link Multiaddr}
747
478
*
@@ -756,7 +487,7 @@ class DefaultMultiaddr implements Multiaddr {
756
487
* @param {MultiaddrInput } [addr] - If String or Uint8Array, needs to adhere to the address format of a [multiaddr](https://github.com/multiformats/multiaddr#string-format)
757
488
*/
758
489
export function multiaddr ( addr ?: MultiaddrInput ) : Multiaddr {
759
- return new DefaultMultiaddr ( addr )
490
+ return new MultiaddrClass ( addr )
760
491
}
761
492
762
493
export { getProtocol as protocols }
0 commit comments