sendmer 0.4.0

A cli tool to send directories over the network, with NAT hole punching
Documentation

Sendmer

English | 中文

Sendmer is a small CLI and reusable Rust library for sending files and directories over the internet with iroh and iroh-blobs.

It is based on n0-computer/sendme v0.31.0, with a codebase that has been gradually reorganized into a clearer library + CLI structure.

Features

  • Send a file or an entire directory with a single command
  • NAT traversal and hole punching via iroh, with relay fallback when needed
  • Verified streaming with blake3 through iroh-blobs
  • Reusable Rust API via exported send and receive functions
  • Optional CLI progress output and clipboard helper

sendmer uses 256-bit node IDs, so tickets remain valid even if IP addresses change during a session. Connections are encrypted with TLS.

Installation

Windows (PowerShell)

# Install latest release
iwr https://raw.githubusercontent.com/bruceblink/sendmer/main/install.ps1 -useb | iex

# Or install a specific version
$env:SENDMER_VERSION="v0.4.0"
iwr https://raw.githubusercontent.com/bruceblink/sendmer/main/install.ps1 -useb | iex

Default install path:

C:\Users\<username>\.sendmer\bin\sendmer.exe

After installation:

  • Add $InstallDir to PATH if needed
  • Restart your terminal
  • Run sendmer --help

Linux / macOS

# Install latest release
curl -fsSL https://raw.githubusercontent.com/bruceblink/sendmer/main/install.sh | bash

# Or install a specific version
SENDMER_VERSION=v0.4.0 \
curl -fsSL https://raw.githubusercontent.com/bruceblink/sendmer/main/install.sh | bash

Default install path:

~/.sendmer/bin/sendmer

If needed, add it to your shell profile:

export PATH="$HOME/.sendmer/bin:$PATH"

Then verify:

sendmer --help

Cargo

cargo install sendmer --locked

Usage

Send

sendmer send <file-or-directory>

This starts a temporary iroh provider, imports the selected file or directory, and prints a receive command with a ticket.

Example:

sendmer send ./my-folder

Typical output:

imported directory my-folder, 12.3 MiB, hash <hash>
to get this data, use
sendmer receive blob:...

The sender keeps running until you stop it with Ctrl+C. When it stops, it shuts down the temporary provider and removes its temporary blob store under the system temp directory.

Receive

sendmer receive <ticket>

This downloads the data and writes it into the current working directory by default.

Example:

sendmer receive <ticket>

Receive-side data is staged in a temporary directory under the system temp directory and cleaned up after completion.

Useful Options

Common options are available on both send and receive:

  • --no-progress: disable CLI progress output
  • -v / -vv: increase log verbosity
  • --relay <default|disabled|url>: control relay usage
  • --magic-ipv4-addr <addr>: bind a fixed IPv4 address
  • --magic-ipv6-addr <addr>: bind a fixed IPv6 address
  • --show-secret: print the secret key used for the current process

Send-specific options:

  • --ticket-type <id|relay-and-addresses|relay|addresses>: control how much addressing information is embedded in the ticket
  • --format <hex|cid>: choose how the imported hash is printed
  • --clipboard: copy the generated sendmer receive ... command to the clipboard

Library Usage

The crate also exposes a small library API:

use sendmer::{receive, send, ReceiveOptions, SendOptions};

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    // let send_result = send(path, SendOptions::default(), None).await?;
    // let receive_result = receive(ticket, ReceiveOptions::default(), None).await?;
    Ok(())
}

The library re-exports:

  • argument and option types
  • transfer event types and EventEmitter
  • send and receive
  • SendResult and ReceiveResult

Development

DEVELOPMENT.md

License

MIT

Sponsor Buy Me Coffee

Contributors