rust-ipfs 0.15.0

IPFS node implementation
Documentation
use rust_ipfs::Ipfs;

use rust_ipfs::builder::IpfsBuilder;
use rust_ipfs::Keypair;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    tracing_subscriber::fmt::init();

    let keypair = Keypair::generate_ed25519();
    let local_peer_id = keypair.public().to_peer_id();

    // Initialize the repo and start a daemon
    let ipfs: Ipfs = IpfsBuilder::with_keypair(&keypair)?
        .with_default()
        .enable_tcp()
        .add_listening_addr("/ip4/0.0.0.0/tcp/0".parse()?)
        .with_mdns()
        .with_relay(true)
        .with_relay_server(Default::default())
        .with_upnp()
        .with_custom_behaviour(move |_| Ok(ext_behaviour::Behaviour::new(local_peer_id)))
        .fd_limit(rust_ipfs::FDLimit::Max)
        .start()
        .await?;

    ipfs.default_bootstrap().await?;
    ipfs.bootstrap().await?;

    // Used to wait until the process is terminated instead of creating a loop
    tokio::signal::ctrl_c().await?;

    ipfs.exit_daemon().await;
    Ok(())
}

mod ext_behaviour {
    use connexa::dummy::DummyHandler;
    use connexa::prelude::swarm::derive_prelude::PortUse;
    use connexa::prelude::swarm::{
        ConnectionDenied, FromSwarm, NewListenAddr, THandler, THandlerInEvent, THandlerOutEvent,
        ToSwarm,
    };
    use connexa::prelude::transport::Endpoint;
    use rust_ipfs::{ConnectionId, Multiaddr, NetworkBehaviour, PeerId};
    use std::convert::Infallible;
    use std::{
        collections::HashSet,
        task::{Context, Poll},
    };

    #[derive(Default, Debug)]
    pub struct Behaviour {
        addrs: HashSet<Multiaddr>,
    }

    impl Behaviour {
        pub fn new(local_peer_id: PeerId) -> Self {
            println!("PeerID: {}", local_peer_id);
            Self {
                addrs: Default::default(),
            }
        }
    }

    impl NetworkBehaviour for Behaviour {
        type ConnectionHandler = DummyHandler;
        type ToSwarm = Infallible;

        fn handle_pending_inbound_connection(
            &mut self,
            _: ConnectionId,
            _: &Multiaddr,
            _: &Multiaddr,
        ) -> Result<(), ConnectionDenied> {
            Ok(())
        }

        fn handle_pending_outbound_connection(
            &mut self,
            _: ConnectionId,
            _: Option<PeerId>,
            _: &[Multiaddr],
            _: Endpoint,
        ) -> Result<Vec<Multiaddr>, ConnectionDenied> {
            Ok(vec![])
        }

        fn handle_established_inbound_connection(
            &mut self,
            _: ConnectionId,
            _: PeerId,
            _: &Multiaddr,
            _: &Multiaddr,
        ) -> Result<THandler<Self>, ConnectionDenied> {
            Ok(DummyHandler)
        }

        fn handle_established_outbound_connection(
            &mut self,
            _: ConnectionId,
            _: PeerId,
            _: &Multiaddr,
            _: Endpoint,
            _: PortUse,
        ) -> Result<THandler<Self>, ConnectionDenied> {
            Ok(DummyHandler)
        }

        fn on_connection_handler_event(
            &mut self,
            _: PeerId,
            _: ConnectionId,
            _: THandlerOutEvent<Self>,
        ) {
        }

        fn on_swarm_event(&mut self, event: FromSwarm) {
            match event {
                FromSwarm::NewListenAddr(NewListenAddr { addr, .. }) => {
                    if self.addrs.insert(addr.clone()) {
                        println!("Listening on {addr}");
                    }
                }
                FromSwarm::ExternalAddrConfirmed(ev) => {
                    if self.addrs.insert(ev.addr.clone()) {
                        println!("Listening on {}", ev.addr);
                    }
                }
                _ => {}
            }
        }

        fn poll(&mut self, _: &mut Context) -> Poll<ToSwarm<Self::ToSwarm, THandlerInEvent<Self>>> {
            Poll::Pending
        }
    }
}