#!/usr/bin/env bash set -euo pipefail ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" ENV_FILE="" MONERO_CLI_INSTALL_PATH="/usr/local/bin/monero-wallet-cli" usage() { cat <&2 usage >&2 exit 1 ;; esac done if [[ -z "$ENV_FILE" ]]; then echo "--env-file is required." >&2 usage >&2 exit 1 fi if [[ "$ENV_FILE" != /* ]]; then ENV_FILE="${ROOT_DIR}/${ENV_FILE#./}" fi if [[ ! -f "$ENV_FILE" ]]; then echo "Env file not found: $ENV_FILE" >&2 exit 1 fi set -a # shellcheck disable=SC1090 source "$ENV_FILE" set +a main() { validate_env ensure_dependencies setup_wallet_config create_wallet_if_missing } validate_env() { local missing=() for var in MONERO_VERSION MONERO_WALLET_DIR MONERO_WALLET_NAME MONERO_NETWORK MONERO_WALLET_PASSWORD; do if [[ -z "${!var:-}" ]]; then missing+=("$var") fi done if [[ ${#missing[@]} -gt 0 ]]; then echo "Missing required env vars in ${ENV_FILE}: ${missing[*]}" >&2 exit 1 fi case "$MONERO_NETWORK" in mainnet | stagenet | testnet) ;; *) echo "MONERO_NETWORK must be mainnet, stagenet, or testnet (got: ${MONERO_NETWORK})." >&2 exit 1 ;; esac } ensure_dependencies() { if ! command -v apt-get >/dev/null 2>&1; then echo "apt-get is required. This script supports Ubuntu/Debian only." >&2 exit 1 fi local missing=() for cmd in curl tar bzip2; do if command -v "$cmd" >/dev/null 2>&1; then log_skip "$cmd" else log_install "$cmd" missing+=("$cmd") fi done if [[ ${#missing[@]} -gt 0 ]]; then run_privileged apt-get update -qq run_privileged apt-get install -y -qq "${missing[@]}" fi install_monero_wallet_cli_if_missing } install_monero_wallet_cli_if_missing() { local arch archive_url tmp_dir extracted_cli if command -v monero-wallet-cli >/dev/null 2>&1; then log_skip "monero-wallet-cli" return fi log_install "monero-wallet-cli" arch="$(uname -m)" case "$arch" in x86_64 | amd64) archive_url="https://downloads.getmonero.org/cli/monero-linux-x64-v${MONERO_VERSION}.tar.bz2" ;; aarch64 | arm64) archive_url="https://downloads.getmonero.org/cli/monero-linux-armv8-v${MONERO_VERSION}.tar.bz2" ;; *) echo "Unsupported CPU architecture: ${arch}" >&2 echo "Install monero-wallet-cli from https://www.getmonero.org/downloads/ and re-run." >&2 exit 1 ;; esac tmp_dir="$(mktemp -d)" trap "rm -rf '${tmp_dir}'" RETURN curl -fsSL "$archive_url" | tar -xj -C "$tmp_dir" extracted_cli="$(find "$tmp_dir" -type f -name monero-wallet-cli | head -n 1)" if [[ -z "$extracted_cli" ]]; then echo "Could not find monero-wallet-cli in the downloaded archive." >&2 exit 1 fi run_privileged install -m 755 "$extracted_cli" "$MONERO_CLI_INSTALL_PATH" } setup_wallet_config() { WALLET_DIR="$(resolve_path "$MONERO_WALLET_DIR")" WALLET_PATH="${WALLET_DIR}/${MONERO_WALLET_NAME}" NETWORK="$MONERO_NETWORK" } resolve_path() { local path="$1" if [[ "$path" != /* ]]; then path="${ROOT_DIR}/${path#./}" fi printf '%s' "$path" } create_wallet_if_missing() { mkdir -p "$WALLET_DIR" chmod 700 "$WALLET_DIR" if [[ -f "$WALLET_PATH" || -f "${WALLET_PATH}.keys" ]]; then echo "Wallet already exists at ${WALLET_PATH} — skipping creation." return fi echo "Creating ${NETWORK} wallet at ${WALLET_PATH}..." monero-wallet-cli "--${NETWORK}" \ --offline \ --log-file /dev/null \ --generate-new-wallet "$WALLET_PATH" \ --password "$MONERO_WALLET_PASSWORD" \ --mnemonic-language English \ --command save chmod 600 "${WALLET_PATH}" "${WALLET_PATH}.keys" 2>/dev/null || true cat </dev/null 2>&1; then sudo "$@" else echo "Root or sudo is required to install missing packages." >&2 exit 1 fi } log_skip() { echo "Package ${1} already installed — skipping." } log_install() { echo "Package ${1} is not installed — installing..." } main