### Start Receiver in Shell Source: https://docs.iroh.computer/quickstart This shell script command initiates the receiver process. It's a straightforward command to start the server-side component. ```shellscript cargo run --bin iroh -- receiver ``` -------------------------------- ### Rust Receiver Endpoint Setup and Ping Handling Source: https://docs.iroh.computer/quickstart This Rust code snippet demonstrates how to set up a receiver endpoint using the Iroh library. It brings the endpoint online, prints its ticket for identification, and then starts a router to continuously accept incoming ping requests. This is essential for establishing communication channels within the Iroh network. ```rust use anyhow::{anyhow, Result}; use iroh::{Endpoint, protocol::Router}; use iroh_ping::Ping; ``` -------------------------------- ### Rust: Receiver Endpoint Setup and Ping Handling Source: https://docs.iroh.computer/quickstart This Rust code illustrates setting up a receiver endpoint, bringing it online, printing its ticket, and then running a router to indefinitely accept incoming ping requests. It assumes the existence of an 'endpoint' object and a 'router' function. ```rust let endpoint = Endpoint::new(); endpoint.set_online().await; let ticket = EndpointTicket::new(endpoint.addr()); println!("{}", ticket); router.run().await; ``` -------------------------------- ### Iroh Router Spawn and Accept Example (Rust) Source: https://docs.iroh.computer/protocols/writing-a-protocol This Rust code snippet demonstrates the basic usage of the Iroh router's `spawn` function to start an accept loop. It also shows how to configure the router with an `accept` call, which requires an ALPN and a `ProtocolHandler`. The example includes a placeholder for a custom `ProtocolHandler` implementation. ```rust use iroh::protocol::{Protocol, ProtocolHandler, Router, RouterBuilder}; use std::io; struct MyProtocolHandler; impl ProtocolHandler for MyProtocolHandler { type Connection = io::Result<()>; async fn handle(&self, _connection: iroh::net::Connection) -> Self::Connection { // Handle the connection logic here Ok(()) } } #[tokio::main] async fn main() -> anyhow::Result<()> { let mut router = RouterBuilder::new(); router.add(Protocol::new("router"), MyProtocolHandler); let router = router.build(); let _ = router.spawn(); // To accept connections, you would typically do something like this: // let mut builder = RouterBuilder::new(); // builder.add(Protocol::new("my_protocol"), MyProtocolHandler); // let router = builder.build(); // let listener = tokio::net::TcpListener::bind("127.0.0.1:12345").await?; // router.accept(Protocol::new("my_protocol"), listener).await?; Ok(()) } ``` -------------------------------- ### Clone and Navigate Iroh Automerge Example Source: https://docs.iroh.computer/protocols/automerge This snippet shows how to clone the iroh-examples repository and navigate into the iroh-automerge directory. It's the initial setup step for running the provided examples. ```bash git clone https://github.com/n0-computer/iroh-examples cd iroh-examples/iroh-automerge ``` -------------------------------- ### Rust Main Function Setup with Tokio Source: https://docs.iroh.computer/quickstart This snippet demonstrates the basic structure of an asynchronous main function in Rust using the Tokio runtime. It includes necessary imports and the function signature for a program that returns a Result. This is a common pattern for applications requiring asynchronous operations. ```rust // filepath: src/main.rs #[tokio::main] async fn main() -> Result<(), ()> { ``` -------------------------------- ### Rust Compilation and Execution Source: https://docs.iroh.computer/quickstart These shell commands demonstrate how to compile and run a Rust project using Cargo, the Rust build system and package manager. The first command initiates the build process, and the second command executes the compiled program, showing example output. ```text cargo run ``` ```shellscript I Compiling ping-pong v0.1.0 ``` -------------------------------- ### Render Quickstart Page Content Source: https://docs.iroh.computer/quickstart This snippet outlines the structure for rendering a 'Quickstart' page. It includes mdxSource and mdxSourceWithNoJs properties, containing compiled source code and frontmatter. ```javascript { "slug": "quickstart", "pageMetadata": "$1b:props:children:props:value:pageMetadata", "theme": "willow", "children": [ // ... other children components { "mdxSource": { "compiledSource": "$4a", "frontmatter": {}, "scope": { "config": {}, "pageMetadata": { "title": "Quickstart", "description": "Start building with iroh in minutes", "href": "/quickstart" } } }, "mdxSourceWithNoJs": { "compiledSource": "$4b", "frontmatter": {}, "scope": { "config": {}, "pageMetadata": { "title": "Quickstart", "description": "Start building with iroh in minutes", "href": "/quickstart" } } } } ] } ``` -------------------------------- ### Setup Router with Accept and Spawn in JavaScript Source: https://docs.iroh.computer/protocols/kv-crdts This JavaScript code snippet demonstrates how to set up a router using the 'builder.accept' method for different ALPN protocols (GOSSIP_ALPN, DOCS_ALPN) and then 'spawn' a new process. It's designed for network communication setup. ```javascript let _router = builder .accept( GOSSIP_ALPN, "gossip" ) .accept( DOCS_ALPN, "docs" ) .spawn(); // do fun stuff with docs! Ok(()) } ``` -------------------------------- ### Rust: Implement and Run Network Communication Protocol Source: https://docs.iroh.computer/protocols/writing-a-protocol This Rust code snippet demonstrates how to implement both the client and server sides of a network communication protocol. It shows how to start an accepting side of a connection and concurrently connect to it, facilitating data exchange. This example utilizes Tokio for asynchronous operations. ```rust #[tokio::main] async fn main() -> Result<(),()> { let router = start_accept_side()?; // ... rest of the code to connect and communicate } ``` -------------------------------- ### Send Ping Messages with Iroh Source: https://docs.iroh.computer/quickstart Demonstrates how to send ping messages using Iroh. It involves creating an endpoint, initializing the Ping protocol, and then using the Ping struct to send a ping to a specified address and measure the round-trip time. This example also shows how to retrieve the endpoint's address to share with a potential receiver. ```rust use anyhow::Result; use iroh::{protocol::Router, Endpoint, Watcher}; use iroh_ping::Ping; #[tokio::main] async fn main() -> Result<()> { // Create an endpoint, it allows creating and accepting // connections in the iroh p2p world let endpoint = Endpoint::bind().await?; // Then we initialize a struct that can accept ping requests over iroh connections let ping = Ping::new(); // receiving ping requests let recv_router = Router::builder(endpoint) .accept(iroh_ping::ALPN, ping) .spawn(); // get the address of this endpoint to share with the sender let addr = recv_router.endpoint().addr(); // create a send side & send a ping let send_ep = Endpoint::bind().await?; let send_pinger = Ping::new(); let rtt = send_pinger.ping(&send_ep, addr).await?; println!("ping took: {:?} to complete", rtt); Ok(()) } ``` -------------------------------- ### Rust Example for iroh-docs Source: https://docs.iroh.computer/protocols This Rust code example demonstrates the basic usage of the iroh-docs crate. It showcases how to initialize the store and perform operations, likely involving document synchronization over a network. ```rust use iroh_docs::store::Store; // Assuming this is the correct import path #[tokio::main] async fn main() -> anyhow::Result<()> { // Example initialization of the store let mut store = Store::new("path/to/your/store").await?; // Example of putting and getting data let doc_id = store.create_document().await?; let key = "my_key".as_bytes(); let value = "my_value".as_bytes(); store.put_bytes(doc_id, key, value).await?; let retrieved_value = store.get_bytes(doc_id, key).await?; println!("Retrieved value: {:?}", retrieved_value); Ok(()) } ``` -------------------------------- ### Install futures-lite Crate for Async Stream Handling Source: https://context7_llms This command installs the `futures-lite` crate, which provides a subset of the `futures` crate's functionality to simplify handling asynchronous streams in Rust. This is a prerequisite for the message reception implementation. ```bash cargo add futures-lite ``` -------------------------------- ### Rust Code Example for EndpointAddr Construction Source: https://docs.iroh.computer/concepts Demonstrates how to construct an EndpointAddr in Rust, showing the initialization of its fields. This example is useful for understanding how to manually create network addresses. ```rust _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#569CD6" }, children: "pub" }), _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#569CD6" }, children: " struct" }), _jsx(_components.span, { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: " EndpointAddr" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: " {" }) }), "\n", _jsxs(_components.span, { className: "line", children: [ _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#569CD6" }, children: " pub" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: " id" }), _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: ":" }), _jsx(_components.span, { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: " PublicKey" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "," }) ] }), "\n", _jsxs(_components.span, { className: "line", children: [ _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#569CD6" }, children: " pub" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: " addrs" }), _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: ":" }), _jsx(_components.span, { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: " BTreeSet" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "<" }), _jsx(_components.span, { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: "TransportAddr" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: ">," }) ] }), "\n", _jsx(_components.span, { className: "line", children: _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "}" }) }), "\n" ] }) ``` -------------------------------- ### Build a P2P Chat App with Iroh Source: https://docs.iroh.computer/examples This example demonstrates how to build a peer-to-peer chat application from scratch using Rust and the Iroh framework. It covers the fundamental steps and concepts required for real-time communication between peers. ```rust const {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0]; const {useMDXComponents: _provideComponents} = arguments[0]; function _createMdxContent(props) { const _components = { p: "p", ..._provideComponents(), ...props.components }, {Card, Columns, Heading} = _components; if (!Card) _missingMdxReference("Card", true); if (!Columns) _missingMdxReference("Columns", true); if (!Heading) _missingMdxReference("Heading", true); return _jsxs(_Fragment, { children: [_jsx(Heading, { level: "2", id: "tutorials", children: "Tutorials" }), "\n", _jsx(_components.p, { children: "Step-by-step guides to learn how to build with iroh." }), "\n", _jsxs(Columns, { cols: 2, children: [_jsx(Card, { title: "chat", icon: "comments", href: "/examples/chat", children: _jsx(_components.p, { children: "Build a p2p chat application in Rust from scratch" }) }), _jsx(Card, { title: "file transfer", icon: "file-arrow-up", href: "/protocols/blobs", children: _jsx(_components.p, children: "Build a peer-to-peer file transfer tool using iroh-blobs" }) })] }), "\n", _jsx(Heading, { level: "2", id: "examples", children: "Examples" }), "\n", ] }); } ``` -------------------------------- ### Start Accepting Side with Iroh Router API Source: https://docs.iroh.computer/protocols/writing-a-protocol Initializes and starts the accepting side of a connection using Iroh's Router API. It binds an endpoint and spawns a router to listen for incoming connections. ```rust async fn start_accept_side() -> anyhow::Result { let endpoint = iroh::Endpoint::.bind().await?; let router = iroh::protocol::Router::builder(endpoint) .spawn(); Ok(router) } ``` -------------------------------- ### Basic iroh-docs Usage Example Source: https://docs.iroh.computer/protocols/kv-crdts This Rust code demonstrates the basic usage of the iroh-docs crate. It covers setting up a document store, adding data, and synchronizing it. This example highlights the core features for distributed data management. ```rust use iroh_docs::store::{Store, Config}; use iroh_net::magic_endpoint::Keypair; use std::path::Path; #[tokio::main] async fn main() -> anyhow::Result<()> { // Create a new store in a temporary directory let path = Path::new("./iroh-docs-example"); let config = Config { path: path.to_path_buf(), ..Default::default() }; let store = Store::new(config).await?; // Create a keypair for the node let keypair = Keypair::new(); // Create a new document let doc = store.create_document(keypair.secret_bytes()).await?; // Insert some data into the document doc.insert_blobs(vec![("hello".to_string(), "world".to_string())]).await?; // Get data from the document let data = doc.get_blobs().await?; println!("Data in document: {:?}", data); // In a real application, you would now set up networking to synchronize // the document with other peers. Ok(()) } ``` -------------------------------- ### JavaScript: Iroh Router Setup and Endpoint Handling Source: https://docs.iroh.computer/protocols/kv-crdts This JavaScript code demonstrates the setup of a router using a 'builder' pattern and defines endpoints for 'GOSSIP_ALPN' and 'DOCS_ALPN'. It also includes a function call to 'spawn()' for further processing. This snippet is likely part of a web server or API implementation. ```javascript jsx(_components.span, { style: { color: "#8250DF", "--shiki-dark": "#DCDCAA" }, children: "builder" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "(" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: "endpoint" }), _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: "." }), _jsx(_components.span, { style: { color: "#8250DF", "--shiki-dark": "#DCDCAA" }, children: "clone" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "());" }), "\n", _jsx(_components.span, { className: "line" }), "\n", _jsx(_components.span, { className: "line", children: _jsx(_components.span, { style: { color: "#6E7781", "--shiki-dark": "#6A9955" }, children: " // setup router" }) }), "\n", _jsxs(_components.span, { className: "line", children: [_jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#569CD6" }, children: " let" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: " _router" }), _jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: " =" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: " builder" })] }), "\n", _jsxs(_components.span, { className: "line", children: [_jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: " ." }), _jsx(_components.span, { style: { color: "#8250DF", "--shiki-dark": "#DCDCAA" }, children: "accept" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "(" }), _jsx(_components.span, { style: { color: "#0550AE", "--shiki-dark": "#D4D4D4" }, children: "GOSSIP_ALPN" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: ", " }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: "gossip" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: ")" })] }), "\n", _jsxs(_components.span, { className: "line", children: [_jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: " ." }), _jsx(_components.span, { style: { color: "#8250DF", "--shiki-dark": "#DCDCAA" }, children: "accept" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "(" }), _jsx(_components.span, { style: { color: "#0550AE", "--shiki-dark": "#D4D4D4" }, children: "DOCS_ALPN" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: ", " }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: "docs" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: ")" })] }), "\n", _jsxs(_components.span, { className: "line", children: [_jsx(_components.span, { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: " ." }), _jsx(_components.span, { style: { color: "#8250DF", "--shiki-dark": "#DCDCAA" }, children: "spawn" }), _jsx(_components.span, { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "();" })] }), "\n", _jsx(_components.span, { className: "line" }), "\n", _jsx(_components.span, { className: "line", children: _jsx(_components.span, { style: { color: "#6E7781", "--shiki-dark": "#6A9955" }, children: " // do fun stuff with docs!" }) }), "\n", _jsxs(_components.span, { className: "line", children: [_jsx(_components.span, { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: " Ok" }), _jsx(_components.span, { style: { color: "#1F23" }) })] }) ``` -------------------------------- ### Constructing Downloader and Initiating Download in Rust Source: https://docs.iroh.computer/protocols/blobs This Rust code snippet shows the process of setting up a file download. It involves parsing CLI arguments to get a 'ticket' and 'path', constructing a 'Downloader' object, and then calling its 'download' method to initiate and wait for the file transfer. ```rust let downloader = Downloader::new(); downloader.download(ticket, path).await?; ``` -------------------------------- ### Configure Page Metadata and Theme Source: https://docs.iroh.computer/quickstart This snippet shows how to configure page metadata and theme settings. It includes placeholders for docsConfig and pageMetadata, which would be populated with specific values. ```javascript { "theme": "willow", "docsConfig": "$1b:props:children:props:children:props:docsConfig", "pageMetadata": "$1b:props:children:props:value:pageMetadata" } ``` -------------------------------- ### Install iroh-doctor CLI Source: https://docs.iroh.computer/deployment/troubleshooting Installs the 'iroh-doctor' command-line tool using Cargo, the Rust package manager. This tool is designed to help diagnose network connectivity issues related to iroh setups. ```bash cargo install iroh-doctor ``` -------------------------------- ### Run Callme CLI Demo for Streaming Source: https://context7_llms Demonstrates how to run the Callme CLI client in both server/listen mode and connect mode to establish a peer-to-peer connection for streaming audio. This requires cloning the Callme repository and using Cargo to build and run the executable. Ensure peers are network-reachable. ```bash git clone https://github.com/n0-computer/callme.git # Terminal A: run the CLI in server/listen mode cd callme/callme-cli cargo run --release -- --listen # Terminal B: run the CLI and connect to the other peer's address cd callme/callme-cli cargo run --release -- --connect ``` -------------------------------- ### Setup Iroh Endpoint with Key-Value Store and Gossip Protocols Source: https://context7_llms Illustrates how to set up an iroh endpoint, integrate the gossip protocol for peer-to-peer communication, and initialize the iroh-docs key-value store. It shows how to build and spawn a router to handle these protocols. ```rust use iroh::{protocol::Router, Endpoint}; use iroh_blobs::{BlobsProtocol, store::mem::MemStore, ALPN as BLOBS_ALPN}; use iroh_docs::{protocol::Docs, ALPN as DOCS_ALPN}; use iroh_gossip::{net::Gossip, ALPN as GOSSIP_ALPN}; #[tokio::main] async fn main() -> anyhow::Result<()> { // create an iroh endpoint that includes the standard discovery mechanisms // we've built at number0 let endpoint = Endpoint::builder().bind().await?; // build the gossip protocol let gossip = Gossip::builder().spawn(endpoint.clone()); // build the docs protocol // use Docs::persistent to use local storage let docs = Docs::memory() .spawn(endpoint.clone(), (*blobs).clone(), gossip.clone()) .await?; // create a router builder, we will add the // protocols to this builder and then spawn // the router let builder = Router::builder(endpoint.clone()); // setup router let _router = builder .accept(GOSSIP_ALPN, gossip) .accept(DOCS_ALPN, docs) .spawn(); // do fun stuff with docs! Ok(()) } ``` -------------------------------- ### Run Iroh Automerge Example (First Terminal) Source: https://docs.iroh.computer/protocols/automerge This command initiates the Iroh Automerge example by running the cargo project. This setup is for the first terminal, which will listen for sync requests using Iroh's connections. ```shellscript # First Terminal > cargo run ``` -------------------------------- ### Rust Example: Setting up Iroh Router Source: https://www.iroh.computer/proto/iroh-gossip This Rust code demonstrates how to set up an Iroh Router, which manages incoming connections and routes them to appropriate protocol handlers based on ALPN. It requires importing necessary components from the iroh crate. ```rust use iroh::protocol::{Router, Endpoint, EndpointId}; #[tokio::main] async fn main() -> anyhow::Result<()> { let endpoint = Endpoint::builder() .bind("127.0.0.1:12345")?; let mut router = Router::new(); // Add protocol handlers to the router here // For example: // router.add_handler(MyProtocolHandler::new()); let listener = endpoint.listen(router).await?; println!("Listening on {:?}", listener.endpoint().port()); // Keep the listener alive // In a real application, you would have logic to handle connections // For this example, we'll just keep it running indefinitely. // listener.await; Ok(()) } // Placeholder for a protocol handler // struct MyProtocolHandler; // impl MyProtocolHandler { // fn new() -> Self { // MyProtocolHandler // } // } // In a real scenario, you would implement the necessary traits for your handler // For example, if you were handling QUIC connections: // #[async_trait::async_trait] // impl quinn::crypto::SessionManager for MyProtocolHandler { // // ... implementation details ... // } ``` -------------------------------- ### JavaScript: Set up Network Endpoint and Send Ping Source: https://docs.iroh.computer/quickstart This snippet demonstrates how to set up a network endpoint and initiate a ping request. It involves creating an endpoint object and then calling the ping method with the endpoint and an address. This is typically used for network communication and latency testing. ```javascript let send_ep = Endpoint::bind(); let send_pinger = Ping::new(); let rtt = send_pinger.ping(&send_ep, addr).await?; ``` -------------------------------- ### Rust EndpointTicket Deserialization Example Source: https://docs.iroh.computer/quickstart This Rust code snippet shows a more detailed example of deserializing an `EndpointTicket`. It explicitly defines the type `EndpointTicket` and calls a `deserialize` method, likely from a serialization library. The code also includes error handling using the `?` operator, indicating that errors from `deserialize` will be propagated. ```rust let ticket: EndpointTicket = EndpointTicket::deserialize(args)?; ``` -------------------------------- ### Define and Import Component Source: https://docs.iroh.computer/quickstart This snippet demonstrates how to define and import a component, ensuring all necessary arguments are provided. It includes error handling for missing imports or arguments. ```javascript function defineAndImportComponent(id) { if (!id) { console.error(``${id}` to be defined: you likely forgot to import, pass, or provide it.`); } } ``` -------------------------------- ### Run Receiver Application with Cargo Source: https://docs.iroh.computer/quickstart This shell script command executes the 'receiver' application using Cargo. It's a prerequisite for sending messages, as it starts the listening service. ```shellscript cargo run -- receiver ``` -------------------------------- ### Setup and Run 'callme' Demo (Shell) Source: https://docs.iroh.computer/protocols/streaming This snippet demonstrates how to clone the iroh repository and set up the 'callme' demo. It requires Git and a Rust toolchain. The commands prepare the environment for running the cross-platform audio exchange demo. ```shellscript git clone https://github.com/n0-computer/iroh cd iroh cd examples/callme ``` -------------------------------- ### Rust Example: Asynchronous 'Get' Request with Connection and Key Source: https://docs.iroh.computer/protocols/rpc This Rust code snippet defines an asynchronous function `get_remote` that performs a 'Get' operation. It takes a connection and a key as input and returns a Result containing an Option of a String. This function is designed for cross-process communication, likely utilizing a serialization library like 'postcard' for data handling. ```rust async fn get_remote(connection: Connection, key: String) -> Result> { // ... implementation details ... } ``` -------------------------------- ### Rust: Define RPC Channels and Requests Source: https://docs.iroh.computer/protocols/rpc This snippet demonstrates how to use the `irpc` crate in Rust to define communication channels for RPC. It shows the setup for `oneshot` and `mpsc` channels, and how to define an enum for RPC requests, including a `KvService` example. ```rust use irpc::channel::{oneshot, mpsc}; #[rpc_requests("KvService", message = RequestWithChannels)] enum Request { // ... other requests } #[rpc(rx = mpsc::Receiver, tx = oneshot::Sender)] // ... other rpc definitions ``` -------------------------------- ### iroh-ping Protocol Handler Source: https://docs.iroh.computer/quickstart This Rust code defines a handler for the 'iroh-ping' protocol. It allows endpoints to exchange ping/pong messages for diagnostic purposes, such as measuring round-trip latency. This serves as an example of using custom or existing protocols over iroh connections. ```rust use iroh_net::endpoint::{Endpoint, EndpointConfig}; use iroh_net::protocol::ProtocolId; use std::io; #[tokio::main] async fn main() -> io::Result<()> { // Configuration for the endpoint let config = EndpointConfig { // ... other configurations ... protocols: vec![ProtocolId::from("iroh-ping")], }; // Create a new iroh endpoint let endpoint = Endpoint::new(config).await?; // Example: Connect to a peer (replace with actual peer address) // let peer_addr = "/ip4/127.0.0.1/tcp/12345/p2p/your_peer_id".parse().unwrap(); // let mut conn = endpoint.connect(peer_addr, ProtocolId::from("iroh-ping")).await?; // Example: Accept incoming connections // tokio::spawn(async move { // while let Some(conn) = endpoint.accept().await { // tokio::spawn(handle_connection(conn)); // } // }); // Placeholder for actual ping/pong logic println!("Endpoint created. Ready to handle iroh-ping protocol."); // Keep the endpoint running (e.g., with a signal handler or other logic) tokio::signal::ctrl_c().await?; Ok(()) } async fn handle_connection(mut conn: iroh_net::endpoint::Connection) -> io::Result<()> { println!("New connection established for iroh-ping."); // Implement ping/pong logic here // For example, read a ping message and send a pong response Ok(()) } ``` -------------------------------- ### Initialize Rust Project and Add Dependencies Source: https://docs.iroh.computer/quickstart Initializes a new Rust project named 'ping-pong' and adds the required Iroh and Tokio dependencies. This sets up the foundational structure for the P2P application. ```bash cargo init ping-pong cd ping-pong ``` ```bash cargo add iroh iroh-ping iroh-tickets tokio anyhow ``` -------------------------------- ### CLI Tool for Direct File Transfers (sendme) Source: https://context7_llms The 'sendme' example is a command-line interface (CLI) tool demonstrating direct file transfers between devices using Iroh. It allows users to easily share files peer-to-peer. ```rust // This is a placeholder for the actual Rust code for the sendme CLI tool. // The full implementation would be found in the sendme GitHub repository. fn main() { println!("Running sendme CLI tool..."); // CLI argument parsing and Iroh file transfer logic would be here. } ``` -------------------------------- ### Send Request via MPSC Channel in Rust Source: https://docs.iroh.computer/protocols/rpc Illustrates how to send a 'Get' request over an MPSC channel in Rust. This snippet assumes a channel has already been established, and it shows the typical pattern of sending a request object. The code is part of a larger example demonstrating client-server communication. ```rust tx.send(Request::Get).await.unwrap(); ``` -------------------------------- ### Initialize Ping Struct and Router for Iroh Connections (Rust) Source: https://docs.iroh.computer/quickstart This snippet demonstrates how to initialize a 'Ping' struct for handling ping requests over iroh connections. It also shows the setup of a 'Router' using a builder pattern to accept these requests, specifying the ALPN and spawning the service. ```rust let ping = Ping::new(); let mut recv_router = Router::builder( endpoint ) .accept( iroh_ping::ALPN, ping ) .spawn(); ``` -------------------------------- ### Main Function Setup for iroh-gossip with Tokio Source: https://context7_llms This Rust code sets up the main function for an iroh-gossip application using Tokio for asynchronous execution. It binds an endpoint, spawns a gossip service, configures a router, subscribes to a topic, sends an initial 'AboutMe' message, and starts the `subscribe_loop` in a separate Tokio task for concurrent message handling. ```rust use std::collections::HashMap; use anyhow::Result; use futures_lite::StreamExt; use iroh::protocol::Router; use iroh::{Endpoint, EndpointId}; use iroh_gossip::{ api::{GossipReceiver, Event}, net::Gossip, proto::TopicId, }; use serde::{Deserialize, Serialize}; #[tokio::main] async fn main() -> Result<()> { let endpoint = Endpoint::bind().await?; println!("> our endpoint id: {}", endpoint.id()); let gossip = Gossip::builder().spawn(endpoint.clone()); let router = Router::builder(endpoint.clone()) .accept(iroh_gossip::ALPN, gossip.clone()) .spawn(); let id = TopicId::from_bytes(rand::random()); let endpoint_ids = vec![]; let (sender, receiver) = gossip.subscribe(id, endpoint_ids).await?.split(); let message = Message::new(MessageBody::AboutMe { from: endpoint.id(), name: String::from("alice"), }); sender.broadcast(message.to_vec().into()).await?; // subscribe and print loop tokio::spawn(subscribe_loop(receiver)); router.shutdown().await?; Ok(()) } ``` -------------------------------- ### Download and Export File with Iroh Source: https://context7_llms Demonstrates how to parse CLI arguments into structs, construct a downloader, initiate a file download using a ticket, and export the downloaded file to a specified path. It also covers gracefully shutting down the iroh endpoint. ```rust let filename: PathBuf = filename.parse()?; let abs_path = std::path::absolute(filename)?; let ticket: BlobTicket = ticket.parse()?; // For receiving files, we create a "downloader" that allows us to fetch files // from other endpoints via iroh connections let downloader = store.downloader(&endpoint); println!("Starting download."); downloader .download(ticket.hash(), Some(ticket.endpoint_addr().id)) .await?; println!("Finished download."); println!("Copying to destination."); store.blobs().export(ticket.hash(), abs_path).await?; println!("Finished copying."); // Gracefully shut down the endpoint println!("Shutting down."); endpoint.close().await; ``` -------------------------------- ### Rust Argument Parsing with Tokio Source: https://docs.iroh.computer/quickstart This Rust code snippet shows how to parse command-line arguments within an asynchronous Tokio environment. It utilizes the `env::args().skip(1)` pattern to get arguments, excluding the program name itself. This is essential for configuring program behavior based on user input. ```rust let mut args = env::args().skip(1); ``` -------------------------------- ### Rust Example: Setting up Iroh Router Source: https://docs.iroh.computer/connecting/gossip This Rust code demonstrates how to set up an Iroh Router, which manages incoming connections and routes them to specific protocol handlers based on ALPN. It requires importing necessary components from the 'iroh' crate. ```rust use iroh::protocol::{Router, Endpoint, EndpointId}; #[tokio::main] async fn main() -> anyhow::Result<()> { let endpoint = Endpoint::new().await?; let mut router = Router::new(endpoint.clone()); // Add protocols to the router here // router.add_protocol(MyProtocol::new()); let addr = endpoint.local_addr(); println!("Listening on {:?}", addr); // Start the router let handle = tokio::spawn(async move { if let Err(e) = router.run().await { eprintln!("Router error: {:?}", e); } }); // Keep the main task alive tokio::signal::ctrl_c().await?; println!("Shutting down..."); // Clean shutdown (optional, depends on how you want to handle it) endpoint.close().await?; handle.abort(); Ok(()) } ``` -------------------------------- ### Clone Iroh Examples Repository Source: https://docs.iroh.computer/protocols/automerge This command clones the iroh-examples repository from GitHub, which contains examples of integrating Automerge with Iroh. This is the first step to running the provided examples. ```shellscript git clone https://github.com/n0-computer/iroh-examples cd iroh-examples ``` -------------------------------- ### Bring Endpoint Online in JavaScript Source: https://docs.iroh.computer/quickstart This code snippet shows how to bring a previously bound network endpoint online. The `endpoint.online()` method is used, and it must be awaited to ensure the endpoint is ready to accept connections. This step is crucial before initiating any network activity. ```javascript // bring the endpoint online before accepting connections endpoint.online(); ``` -------------------------------- ### Establish iroh Endpoint Connection Source: https://docs.iroh.computer/quickstart This code snippet demonstrates how to establish an iroh Endpoint connection. It involves defining styles for different parts of the endpoint string and using JSX for rendering. The code shows the structure for connecting and accepting connections. ```jsx _jsx("div", { children: [ _jsx("_components.span", { style: { color: "#1F2328", "--shiki-dark": "#9CDCFE" }, children: " endpoint" }), _jsx("_components.span", { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: " =" }), _jsx("_components.span", { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: " Endpoint" }), _jsx("_components.span", { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: "::" }), _jsx("_components.span", { style: { color: "#8250DF", "--shiki-dark": "#DCDCAA" }, children: "bind" }), _jsx("_components.span", { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "()" }), _jsx("_components.span", { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: "." }), _jsx("_components.span", { style: { color: "#CF222E", "--shiki-dark": "#C586C0" }, children: "await" }), _jsx("_components.span", { style: { color: "#CF222E", "--shiki-dark": "#D4D4D4" }, children: "?" }), _jsx("_components.span", { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: ";" }) ] }), "\n", _jsx("_components.span", { className: "line" }), "\n", _jsx("_components.span", { className: "line", children: _jsx("_components.span", { style: { color: "#6E7781", "--shiki-dark": "#6A9955" }, children: " // ..." }) }), "\n", _jsx("_components.span", { className: "line" }), "\n", _jsxs("_components.span", { className: "line", children: [ _jsx("_components.span", { style: { color: "#953800", "--shiki-dark": "#4EC9B0" }, children: " Ok" }), _jsx("_components.span", { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "(())" }) ] }), "\n", _jsx("_components.span", { className: "line", children: _jsx("_components.span", { style: { color: "#1F2328", "--shiki-dark": "#D4D4D4" }, children: "}" }) }), "\n" ] ``` -------------------------------- ### Set Up Router for iroh-blobs Connections Source: https://context7_llms This code configures and starts a router for handling incoming iroh-blobs connections. It uses the `Router::builder` to create a router associated with the endpoint and configures it to accept connections for the `iroh_blobs::ALPN` protocol, routing them to the `blobs` handler. The router is then spawned to run in the background. The snippet also includes graceful shutdown logic triggered by a `Ctrl+C` signal. ```rust // For sending files we build a router that accepts blobs connections & // routes them // to the blobs protocol. let router = Router::builder(endpoint) .accept(iroh_blobs::ALPN, blobs) .spawn(); tokio::signal::ctrl_c().await?; // Gracefully shut down the endpoint println!("Shutting down."); router.shutdown().await?; ``` -------------------------------- ### Clone Iroh Examples Repository Source: https://docs.iroh.computer/protocols/automerge This command clones the iroh-examples repository, which contains various examples demonstrating Iroh's capabilities. It's a prerequisite for running the provided Automerge integration example. ```shellscript git clone https://github.com/n0-computer/iroh-examples ``` -------------------------------- ### Voice and Video Calling Application (callme) Source: https://context7_llms The 'callme' example showcases a voice and video calling application built with Iroh. This demonstrates Iroh's capabilities in handling real-time media streams for P2P communication. ```rust // This is a placeholder for the actual Rust code for the callme application. // The full implementation would involve Iroh's networking and media streaming features. fn main() { println!("Starting callme voice and video application..."); // Iroh connection setup, media capture, and streaming logic would be here. } ```