Shadowsprout is a Rust-based decentralized VPN client with:
- a local terminal UI (Ratatui) to select and connect to VPN providers,
- OpenVPN process orchestration for tunnel startup/teardown,
- integration with an Ethereum-backed Gear/Ethexe contract for provider discovery, provider file upload, and reputation ranking.
The binary crate name is shadowsprout.
src/main.rs— CLI entrypoint and command routing.src/tui.rs— interactive TUI flow, provider ranking interactions, deploy/upload helpers, key management.src/vpn.rs— OpenVPN config staging, credential handling, process spawning, cancellation logic.src/contract.rs— local mock contract data types and helper API surface.contract/— smart-contract workspace members (app/,client/) and generated interfaces.
- CLI parses
connectarguments. - Ethereum and Vara/Ethexe API clients are initialized.
- TUI loads providers from contract and fetches each provider's VPN file metadata.
- User selects a provider.
- If OpenVPN profile requires
auth-user-pass, credentials are collected (CLI args or prompt). - OpenVPN config is staged in a temporary directory.
- Native
openvpnprocess is spawned and monitored. - Provider is ranked up/down based on connection result.
- Connect to RPC and router contract.
- Upload/validate WASM code if needed.
- Create program actor.
- Approve and top-up balances.
- Send create/init message and await successful reply.
- Parse provider key hex.
- Read VPN config file content.
- Build
AddProviderFilemessage. - Send message and await reply.
- Report whether provider was inserted or replaced.
- Rust toolchain compatible with the project (
rust-toolchain.toml). - OpenVPN installed locally (required for
connect). - Access to configured RPC/WebSocket endpoints.
- A signing key imported for sending authenticated contract operations.
cargo buildRelease build:
cargo build --releaseGeneral help:
cargo run -- --help- Import key first (required): import the private key that corresponds to the same address you will use as
SENDER_ADDRESS. - Set
SENDER_ADDRESS(or pass--sender-addresswhere required). - Run
connect,deploy-contract, orupload-filecommands.
Without importing the matching key, sender-authenticated operations will fail.
cargo run -- import-key <PRIVATE_KEY>cargo run -- connect \
--sender-address <ETH_ADDRESS> \
--router-address <ROUTER_ADDRESS> \
--vpn-address <VPN_CONTRACT_ADDRESS>When OpenVPN profile needs credentials, either provide both:
--ovpn-username <USER> --ovpn-password <PASS>or enter credentials interactively in the TUI.
cargo run -- deploy-contract(Requires SENDER_ADDRESS if not passed through CLI where applicable.)
cargo run -- upload-file \
--sender-address <ETH_ADDRESS> \
--provider-key <32_BYTE_HEX> \
--name <PROVIDER_NAME> \
--kind <openvpn|wireguard> \
--file <PATH_TO_CONFIG>SENDER_ADDRESS— default sender address for commands that require it.ROUTER_ADDRESS— router contract address (used byconnectby default).VPN_ADDRESS— VPN contract address (used byconnectby default).OPENVPN_BIN— optional explicit path to OpenVPN binary.PATH— searched foropenvpnwhenOPENVPN_BINis not set.
- Provider ranking is adjusted after each attempt (
+1on success,-1on failure). - Failed providers are marked in UI and skipped during navigation.
- OpenVPN credentials are written to a temporary auth file only when required by profile.
- Temporary staging directory is retained for session lifetime and cleaned when session ends.
- The TUI uses raw terminal mode and alternate screen; exiting restores terminal state.
- Use
cargo checkfor quick type/lint-style verification. - Use
cargo run -- connect ...for end-to-end client flow testing. - Keep contract-side ABI/client updates in sync with
contract/clientgenerated interfaces.
openvpn binary not found: install OpenVPN or setOPENVPN_BIN.- Invalid address parsing errors: verify hex formatting and expected chain address values.
- Contract reply not successful: inspect returned code/payload and verify RPC/router/contract endpoints.
- Connection timeouts: ensure provider config endpoint/network path is reachable and OpenVPN can route.