o
    jGz                     @  s  d Z ddlmZ ddlZddlmZ ddlZddlZddlm	Z	 ddl
mZmZmZ er2ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ ddlmZmZ ddlmZ ddl
mZmZ ddl Z ddl!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z' ddl(m)Z)m*Z* ddl+m,Z, ddl-m.Z. ddl/m0Z0m1Z2 ddl3m1Z4 ddl5m1Z6 ddl7m8Z8m9Z9m:Z: ddl;m<Z< ddl=m>Z> ddl?m@Z@ ddlAmBZBmCZC ddlDmEZE ddlFmGZGmHZH ddlImJZJmKZKmLZLmMZMmNZNmOZOmPZPmQZQmRZRmSZS ddlTZTddlUmVZVmWZW ddlXmYZZm[Z\ ddl]mYZ^m_Z_ ddl`ma  mb  mcZb dd ldmeZemfZf dd!lgmYZhmiZi dd"ljmkZk dd#llmmZm ddlnZTdd$lompZp ddlqZTep  d%ard%Zsd&Ztd'ZuevewZxdd,d-Zyddd3d4Zzddd6d7Z{dd8d9Z|dd;d<Z}dd=d>Z~dd?d@ZddAdBZddDdEZddFdGZ	ddd\d]Z								^	^	^	_	^								dddudvZdddddddd^d^d^d^deud^d^dddddd^dwdxdddd_d^fdddZedZdS )zLibp2p Python implementation.    )annotationsN)Path)is_quic_multiaddr)TYPE_CHECKINGAnycastPortDemultiplexer)ed25519)serialization)QUICTransport)QUICTransportConfig)MappingSequence)version)LiteralOptional)IHostINetworkServiceIPeerRouting
IPeerStoreISecureTransport
ITransport)ChannelBridgeListenerEventBus)ResourceManager)KeyPair)Ed25519PrivateKeycreate_new_key_pair)r   )TMuxerOptions	TProtocolTSecurityOptions)	BasicHost)
RoutedHost)Swarm)ConnectionConfigRetryConfig)ID)	PeerStorecreate_signed_peer_record)
create_sync_peerstorecreate_async_peerstorecreate_sync_sqlite_peerstorecreate_async_sqlite_peerstorecreate_sync_memory_peerstorecreate_async_memory_peerstorecreate_sync_leveldb_peerstorecreate_async_leveldb_peerstorecreate_sync_rocksdb_peerstorecreate_async_rocksdb_peerstore)PLAINTEXT_PROTOCOL_IDInsecureTransport)PROTOCOL_ID	Transport)r6   TLSTransport)MPLEX_PROTOCOL_IDMplex)r6   Yamux)TCP)TransportUpgrader)setup_loggingZYAMUXMPLEX   
muxer_nameLiteral['YAMUX', 'MPLEX']returnNonec                 C  s,   |   }|ttfvrtd|  d|adS )z
    Set the default multiplexer protocol to use.

    :param muxer_name: Either "YAMUX" or "MPLEX"
    :raise ValueError: If an unsupported muxer name is provided
    Unknown muxer: . Use 'YAMUX' or 'MPLEX'.N)upperMUXER_YAMUXMUXER_MPLEX
ValueErrorDEFAULT_MUXER)rA   Zmuxer_upper rL   2/Users/sumanjeet/code/py-libp2p/libp2p/__init__.pyset_default_muxer   s   rN   r
   key_pairr   typestrc                 C  sp   | j }|dkr0t|tsJ | }tj|}|jtjj	tj
jt d}tjjj| dS 	 td| )ab  
    Persist a private key to disk in PEM format.

    Currently supports only Ed25519 keys. Writes the key to a predefined
    path for later retrieval.

    :param key_pair: KeyPair object containing private and public keys.
    :param type: Type of key to save (default: "ed25519").
    :raises ValueError: if an unsupported key type is provided.
    r
   encodingformatZencryption_algorithmunsupported key type: N)private_key
isinstancer   to_bytesr
   Zfrom_private_bytesprivate_bytesr   EncodingZPEMPrivateFormatZPKCS8NoEncryptionlibp2putilspathsED25519_PATHwrite_bytesrJ   )rO   rP   pvt_keyraw
crypto_keypemrL   rL   rM   save_keypair   s   rf   KeyPair | Nonec                 C  s   | dkr>t jjj}| sdS | }tj|dd}t|t	j
s"J |jtjjtjjt d}t
|}| }t||S 	 td|  )aJ  
    Load a private key from disk and reconstruct its KeyPair.

    Currently supports only Ed25519 keys. Returns None if the key file does
    not exist.

    :param type: Type of key to load (default: "ed25519").
    :return: KeyPair object if found, or None.
    :raises ValueError: if an unsupported key type is provided.
    r
   N)passwordrR   rU   )r]   r^   r_   r`   exists
read_bytesr   Zload_pem_private_keyrW   r
   r   rY   rZ   ZRawr[   r\   
from_bytesZget_public_keyr   rJ   )rP   pathre   rd   rc   rb   Zpub_keyrL   rL   rM   load_keypair   s*   


rm   c                   C  s   t S )z_
    Returns the currently selected default muxer.

    :return: Either "YAMUX" or "MPLEX"
    )rK   rL   rL   rL   rM   get_default_muxer   s   rn   r   c                   C     t ttt ttiS )zn
    Returns muxer options with Yamux as the primary choice.

    :return: Muxer options with Yamux first
    )r    YAMUX_PROTOCOL_IDr;   r9   r:   rL   rL   rL   rM   create_yamux_muxer_option      rq   c                   C  ro   )zn
    Returns muxer options with Mplex as the primary choice.

    :return: Muxer options with Mplex first
    )r    r9   r:   rp   r;   rL   rL   rL   rM   create_mplex_muxer_option   rr   rs   c                   C     t  S N)create_new_rsa_key_pairrL   rL   rL   rM   generate_new_rsa_identity  s   rw   c                   C  rt   )z
    Generate a new Ed25519 identity key pair.

    Ed25519 is preferred for better interoperability with other libp2p implementations
    (e.g., Rust, Go) which often disable RSA support.
    )create_new_ed25519_key_pairrL   rL   rL   rM   generate_new_ed25519_identity  s   ry   r'   c                 C  s   | j }t|S ru   )
public_keyr'   Zfrom_pubkey)rO   rz   rL   rL   rM   generate_peer_id_from  s   
r{   c                   C  s   t dkrt S t S )z
    Returns the default muxer options based on the current default muxer setting.

    :return: Muxer options with the preferred muxer first
    r?   )rK   rs   rq   rL   rL   rL   rM   get_default_muxer_options  s   r|   listen_addrs$Sequence[multiaddr.Multiaddr] | None
transportsSequence[ITransport] | Noneenable_quicboolenable_webrtc
enable_tcpenable_websocketenable_autotlsupgraderr=   quic_configQUICTransportConfig | Nonetls_client_configssl.SSLContext | Nonetls_server_config
quic_classtype | Nonelist[ITransport]c                 C  s(  |durt |S |dur|nt}g }|rt }|D ]}dd | D }d}d|v r6d|vr6d|vr6t }nfd|v s>d|v rQ| du rHtd	 q|| j|	|d
}nKd|v sYd|v rgddlm	} |||
|d}n5d|v rddl
m} | du r{td q|| jd}nd|v rddlm} | du rtd q|| jd}|du rqt|}||vr|| || q|rtdd |D s|| j|	|d
g}|s|r||| j|	|d
 |rddlm	} ||||
|d |rddl
m} | du rtd n	||| jd |s|s|t  |S )u[  
    Build the ordered list of transports for the Swarm's TransportManager.

    Priority:
    1. Explicit ``transports`` list — used as-is (highest priority).
    2. ``listen_addrs`` inspection — auto-detects which transports are needed
       by inspecting **every** address (not just the first one).
    3. ``enable_*`` flags — coarse-grained control when no addresses given.
    4. Default fallback: TCP only.

    :param key_pair: The host's key pair (needed by QUIC for TLS).
    :param listen_addrs: The multiaddrs the host will listen on.
    :param transports: Explicit transport list, or ``None`` to auto-build.
    :param enable_quic: Whether to create a QUIC transport when auto-building.
    :param enable_webrtc: Whether to create a WebRTC transport when auto-building.
    :param enable_tcp: Whether to include a TCP transport when auto-building.
    :param enable_websocket: Whether to include a WebSocket transport.
    :param enable_autotls: Whether to enable AutoTLS in QUIC/WebSocket transports.
    :param upgrader: The upgrader passed to WebSocket transport at construction.
    :param quic_config: Optional QUIC transport configuration.
    :param tls_client_config: TLS client context for WebSocket.
    :param tls_server_config: TLS server context for WebSocket.
    :returns: Ordered list of :class:`~libp2p.abc.ITransport` instances.
    Nc                 S  s   g | ]}|j qS rL   name.0prL   rL   rM   
<listcomp>T      z/_build_transports_for_swarm.<locals>.<listcomp>tcpwswssZquiczquic-v1z.QUIC transport requires key_pair (private_key))configr   r   )WebsocketTransport)r   r   zwebrtc-direct)WebRTCDirectTransportz0WebRTC transport requires key_pair (private_key))rV   Zwebrtc)WebRTCPrivateTransportc                 s  s    | ]
}t |jd kV  qdS )r   NrP   __name__r   trL   rL   rM   	<genexpr>  s    z._build_transports_for_swarm.<locals>.<genexpr>)listr   set	protocolsr<   loggerwarningrV   Z$libp2p.transport.websocket.transportr   Z!libp2p.transport.webrtc.transportr   Z)libp2p.transport.webrtc.private_transportr   rP   addappendany)rO   r}   r   r   r   r   r   r   r   r   r   r   r   Z_QUICTransportresultZseen_classesaddrr   Ztransport_objr   r   r   clsrL   rL   rM   _build_transports_for_swarm   s   )




	r   FT	muxer_optTMuxerOptions | Nonesec_optTSecurityOptions | Nonepeerstore_optIPeerStore | Nonemuxer_preference Literal['YAMUX', 'MPLEX'] | Noneretry_configRetryConfig | Noneconnection_config-ConnectionConfig | QUICTransportConfig | Noneresource_managerResourceManager | Nonepsk
str | Nonemetric_send_channel"trio.MemorySendChannel[Any] | None	event_busEventBus | Noner   c           0      C  s  | du rt  } t| }t|tr|nd}t }|p7tt| |jdtt	| |	dt
tjt| t
tt| |di}|durQ| }|ttfvrNtd| d|}nt}|durZ|}n|tkrbt }nt }t||d}t| |||||
||	||||td}td	d
d |D  |pt }|||  d}i }|rddlm}  i }!|D ]F}"z;dd |"  D }#d|#vrW q|"!dp|"!d}$|"!d}%|$du s|%du rW qt"|$t#|%f}&|!$|&g %|# W q t&y   Y qw |!' D ].\\}'}(})t(dd |)D }*t(dd |)D }+|*r|+r| |'|(||'|(f< td|'|( qddl)m*}, |,|d}-t+||||||||||-d
}.|du rSzddl,m-}/ |/ }W n t&yR   d}Y nw |dur]|..| |.S )uN  
    Create a swarm instance with multi-transport support.

    The swarm can listen on and dial over multiple transports simultaneously
    (TCP, WebSocket, QUIC), mirroring go-libp2p's architecture.

    Transport selection priority (highest to lowest):

    1. **Explicit ``transports`` list** — used as-is; all other transport
       parameters are ignored.
    2. **``listen_addrs`` inspection** — each address is inspected to determine
       which transports are needed (TCP, WebSocket, QUIC).  All detected
       transport types are created and registered.
    3. **``enable_*`` flags** — coarse-grained control when no addresses are
       provided (``enable_quic``, ``enable_websocket``, ``enable_tcp``).
    4. **Default fallback** — TCP only.

    :param key_pair: optional choice of the ``KeyPair``
    :param muxer_opt: optional choice of stream muxer
    :param sec_opt: optional choice of security upgrade
    :param peerstore_opt: optional peerstore
    :param muxer_preference: optional explicit muxer preference (``"YAMUX"`` or
        ``"MPLEX"``)
    :param listen_addrs: optional list of multiaddrs to listen on.  **All**
        addresses are inspected to determine which transports to create.
    :param transports: explicit list of transport instances to register.  When
        provided, all ``enable_*`` flags and ``listen_addrs``-based detection
        are bypassed.
    :param enable_quic: include a QUIC transport when auto-building (deprecated;
        prefer passing ``listen_addrs`` with QUIC addresses or ``transports``).
    :param enable_autotls: enable AutoTLS for QUIC / WebSocket transports.
    :param enable_tcp: include a TCP transport when auto-building (default True).
    :param enable_websocket: include a WebSocket transport when auto-building.
    :param retry_config: optional connection retry configuration.
    :param connection_config: optional connection configuration.
    :param tls_client_config: TLS client context for WebSocket transport.
    :param tls_server_config: TLS server context for WebSocket transport.
    :param resource_manager: optional resource manager for connection/stream limits.
    :param psk: optional pre-shared key for PSK encryption.
    :return: a Swarm instance implementing INetworkService.

    Examples::

        # TCP only (default)
        swarm = new_swarm()

        # TCP + WebSocket + QUIC auto-detected from listen_addrs
        swarm = new_swarm(listen_addrs=[
            Multiaddr("/ip4/0.0.0.0/tcp/4001"),
            Multiaddr("/ip4/0.0.0.0/tcp/4002/ws"),
            Multiaddr("/ip4/0.0.0.0/udp/4003/quic-v1"),
        ])

        # Explicit transport list
        swarm = new_swarm(transports=[TCP(), QUICTransport(kp.private_key)])

    Note: Yamux (/yamux/1.0.0) is the preferred stream multiplexer
          due to its improved performance and features.
          Mplex (/mplex/6.7.0) is retained for backward compatibility
          but may be deprecated in the future.

    Note: Ed25519 keys are used by default for better interoperability with
          other libp2p implementations (Rust, Go) which often disable RSA support.
    N)Znoise_privkey)r   )	peerstorerE   rF   )secure_transports_by_protocolmuxer_transports_by_protocol)rO   r}   r   r   r   r   r   r   r   r   r   r   r   znew_swarm: using transports: %sc                 S  s   g | ]}t |jqS rL   r   r   rL   rL   rM   r   Q  s    znew_swarm.<locals>.<listcomp>r   r   c                 S  s   h | ]}|j qS rL   r   r   rL   rL   rM   	<setcomp>f  r   znew_swarm.<locals>.<setcomp>r   Zip4Zip6c                 s  s     | ]}d |vod|vV  qdS r   r   NrL   r   psrL   rL   rM   r   w  s    
znew_swarm.<locals>.<genexpr>c                 s  s     | ]}d |v pd|v V  qdS r   rL   r   rL   rL   rM   r   z  s    z:new_swarm: created PortDemultiplexer for shared port %s:%d)TransportManager)port_demuxers)r   r   r   r   r   r   transport_managernew_resource_manager)/ry   r{   rW   r   create_new_x25519_key_pairNOISE_PROTOCOL_IDNoiseTransportrV   TLS_PROTOCOL_IDr8   r    secior'   r7   r4   r5   rG   rH   rI   rJ   rK   rs   rq   r=   r   r   r   debugr(   Zadd_key_pairlibp2p.transport.cmuxr	   r   Zvalue_for_protocolrQ   int
setdefaultr   	Exceptionitemsr   Zlibp2p.transport.managerr   r$   libp2p.rcmgrr   Zset_resource_manager)0rO   r   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zid_optquic_transport_optZnoise_key_pairr   Z	temp_prefZactive_preferencer   r   Ztransport_listr   Z
port_demuxr   Z_ConnMgrZport_protosr   protosZhost_valZport_valkeyhostportZ
proto_setsZhas_plain_tcpZhas_wsr   r   swarm_new_rmrL   rL   rM   	new_swarm  s   Y








r   g      $@   disc_optIPeerRouting | Noneenable_mDNSenable_upnpenable_metrics	bootstraplist[str] | Nonenegotiate_timeoutr   r   bootstrap_allow_ipv6bootstrap_dns_timeoutfloatbootstrap_dns_max_retriesConnectionConfig | Noneannounce_addrsr   c           "      C  sR  |s|durt d t }d\}}|
r"td\}}|t| |du r=zddlm} | }W n t	y<   d}Y nw |rF|durF|} n|} t
di d|d|d	| d
|d|d|d|	d|d|d| d|d|d|d|d|d|d|d|d|}!|durt|!||||||||||dS t|!|||||||||||dS )u`	  
    Create a new libp2p host based on the given parameters.

    The host can listen on and dial over multiple transports simultaneously
    (TCP, WebSocket, QUIC), mirroring go-libp2p's architecture.

    Transport selection priority (highest to lowest):

    1. ``transports`` — explicit list, used as-is.
    2. ``listen_addrs`` inspection — all addresses are inspected.
    3. ``enable_*`` flags.
    4. Default: TCP only.

    :param key_pair: optional choice of the ``KeyPair``
    :param muxer_opt: optional choice of stream muxer
    :param sec_opt: optional choice of security upgrade
    :param peerstore_opt: optional peerstore
    :param disc_opt: optional discovery
    :param muxer_preference: optional explicit muxer preference
    :param listen_addrs: optional list of multiaddrs to listen on.  **All**
        addresses are inspected to determine which transports to create.
    :param enable_mDNS: whether to enable mDNS discovery
    :param bootstrap: optional list of bootstrap peer addresses as strings
    :param enable_quic: optional choice to use QUIC for transport
    :param enable_autotls: optional choice to use AutoTLS for security
    :param quic_transport_opt: optional configuration for quic transport
    :param tls_client_config: optional TLS client configuration for WebSocket transport
    :param tls_server_config: optional TLS server configuration for WebSocket transport
    :param resource_manager: optional resource manager for connection/stream limits
    :type resource_manager: :class:`libp2p.rcmgr.ResourceManager` or None
    :param psk: optional pre-shared key (PSK)
    :param bootstrap_allow_ipv6: if True, bootstrap accepts IPv6+TCP addresses
    :param bootstrap_dns_timeout: DNS resolution timeout in seconds per attempt
    :param bootstrap_dns_max_retries: max DNS resolution retries with backoff
    :param connection_config: optional connection configuration for connection manager
    :param announce_addrs: if set, these replace listen addrs in get_addrs()
    :param transports: explicit list of transport instances to register.  When
        provided, all ``enable_*`` flags and ``listen_addrs``-based detection
        are bypassed.
    :param enable_tcp: include a TCP transport when auto-building (default True).
    :param enable_websocket: include a WebSocket transport when auto-building.
    :return: return a host instance
    Nz?QUIC config provided but QUIC not enabled, ignoring QUIC config)NNd   r   r   r   r   rO   r   r   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   )networkrouterr   r   r   r   r   r   r   r   r   )r   r   r   r   r   r   metric_recv_channelr   r   r   r   r   rL   )r   r   r   trioopen_memory_channelZregister_listenerr   r   r   r   r   r#   r"   )"rO   r   r   r   r   r   r}   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   Zeffective_configr   rL   rL   rM   new_host  s   L

	
r   r]   )rA   rB   rC   rD   )rO   r   rP   rQ   rC   rD   )rP   rQ   rC   rg   )rC   rQ   )rC   r   )rC   r   )rO   r   rC   r'   ru   )rO   r   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r=   r   r   r   r   r   r   r   r   rC   r   )NNNNNNNFFFTFNNNNNNNN)*rO   rg   r   r   r   r   r   r   r   r   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rC   r   ):rO   rg   r   r   r   r   r   r   r   r   r   r   r}   r~   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r~   r   r   r   r   r   r   rC   r   )__doc__
__future__r   loggingpathlibr   sslr   Zlibp2p.transport.quic.utilsr   typingr   r   r   r   r	   Z)cryptography.hazmat.primitives.asymmetricr
   Zcryptography.hazmat.primitivesr   Zlibp2p.transport.quic.transportr   Zlibp2p.transport.quic.configr   collections.abcr   r   importlib.metadatar   Z	__versionr   r   Z	multiaddr
libp2p.abcr   r   r   r   r   r   Zlibp2p.eventsr   r   r   r   Zlibp2p.crypto.keysr   Zlibp2p.crypto.ed25519r   r   rx   Zlibp2p.crypto.rsarv   Zlibp2p.crypto.x25519r   Zlibp2p.custom_typesr   r    r!   Zlibp2p.host.basic_hostr"   Zlibp2p.host.routed_hostr#   Zlibp2p.network.swarmr$   Zlibp2p.network.configr%   r&   Zlibp2p.peer.idr'   Zlibp2p.peer.peerstorer(   r)   Zlibp2p.peer.persistentr*   r+   r,   r-   r.   r/   r0   r1   r2   r3   r]   Z"libp2p.security.insecure.transportr4   r5   Zlibp2p.security.noise.transportr6   r   r7   r   Zlibp2p.security.tls.transportr   r8   Zlibp2p.security.secio.transportsecurityr   	transportZlibp2p.stream_muxer.mplex.mplexr9   r:   Zlibp2p.stream_muxer.yamux.yamuxrp   r;   Zlibp2p.transport.tcp.tcpr<   Zlibp2p.transport.upgraderr=   Zlibp2p.utilsZlibp2p.utils.loggingr>   Zlibp2p.utils.pathsrK   rH   rI   ZDEFAULT_NEGOTIATE_TIMEOUT	getLoggerr   r   rN   rf   rm   rn   rq   rs   rw   ry   r{   r|   r   r   r   __version__rL   rL   rL   rM   <module>   s     0


(
	





  x $