#!/bin/sh set -eu # Everything runs from main, called on the last line, so a download cut off # mid-stream under `curl | sh` defines nothing and runs nothing. main() { version=${CONE_VERSION:-0.3.1} release_base=${CONE_RELEASE_BASE:-https://cone.chat/releases} bin_dir=${CONE_BIN_DIR:-"$HOME/.local/bin"} network= peer= peer_name= exec_command= agent_name= while [ "$#" -gt 0 ]; do case "$1" in --env|--connect|--name|--exec|--agent-name) [ "$#" -ge 2 ] || { echo "Missing value for $1" >&2; exit 1; } case "$1" in --env) network=$2 ;; --connect) peer=$2 ;; --name) peer_name=$2 ;; --exec) exec_command=$2 ;; --agent-name) agent_name=$2 ;; esac shift 2 ;; *) echo "Usage: install.sh [--exec ''] [--agent-name ] [--connect ] [--name ] [--env production|dev]" >&2; exit 1 ;; esac done case "$version" in ''|*[!A-Za-z0-9.-]*) echo "Invalid Cone version" >&2; exit 1 ;; esac case "$network" in ''|production|dev|local) ;; *) echo "Invalid XMTP environment" >&2; exit 1 ;; esac case "$(uname -s)/$(uname -m)" in Darwin/arm64) target=darwin-arm64 ;; Linux/x86_64) target=linux-x64 ;; Linux/aarch64|Linux/arm64) target=linux-arm64 ;; *) echo "No Cone executable for $(uname -s)/$(uname -m). See the source installation instructions." >&2; exit 1 ;; esac command -v curl >/dev/null || { echo "curl is required to download Cone" >&2; exit 1; } temporary=$(mktemp -d) staged= trap 'rm -rf "$temporary"; if [ -n "$staged" ]; then rm -f "$staged"; fi' EXIT trap 'exit 1' HUP INT TERM archive="cone-$version-$target.tar.gz" url="$release_base/v$version" printf 'Downloading Cone %s for %s…\n' "$version" "$target" >&2 curl --fail --show-error --silent --location "$url/$archive" -o "$temporary/$archive" curl --fail --show-error --silent --location "$url/SHA256SUMS" -o "$temporary/SHA256SUMS" expected=$(awk -v file="$archive" '$2 == file {print $1}' "$temporary/SHA256SUMS") [ "${#expected}" -eq 64 ] || { echo "Release checksum is missing or invalid" >&2; exit 1; } if command -v sha256sum >/dev/null; then actual=$(sha256sum "$temporary/$archive" | awk '{print $1}') else actual=$(shasum -a 256 "$temporary/$archive" | awk '{print $1}') fi [ "$actual" = "$expected" ] || { echo "Cone download failed checksum verification" >&2; exit 1; } tar -xOzf "$temporary/$archive" cone > "$temporary/cone" tar -xOzf "$temporary/$archive" xmtp.node > "$temporary/xmtp.node" tar -xOzf "$temporary/$archive" LICENSE > "$temporary/LICENSE" tar -xOzf "$temporary/$archive" THIRD_PARTY_NOTICES.txt > "$temporary/THIRD_PARTY_NOTICES.txt" mkdir -p "$bin_dir" # The executable finds XMTP's native library at ../lib/cone//. lib_dir="$(dirname "$bin_dir")/lib/cone/$version" mkdir -p "$lib_dir" install -m 644 "$temporary/xmtp.node" "$lib_dir/xmtp.node.next" mv -f "$lib_dir/xmtp.node.next" "$lib_dir/xmtp.node" staged="$bin_dir/.cone-$version-$$" install -m 755 "$temporary/cone" "$staged" [ "$("$staged" --version)" = "cone $version" ] || { echo "Release executable has the wrong version" >&2; exit 1; } mv -f "$staged" "$bin_dir/cone" staged= binary="$bin_dir/cone" license_dir=${CONE_HOME:-"$HOME/.local/share/cone"}/licenses mkdir -p "$license_dir" install -m 644 "$temporary/LICENSE" "$license_dir/Cone.txt" install -m 644 "$temporary/THIRD_PARTY_NOTICES.txt" "$license_dir/THIRD_PARTY_NOTICES.txt" printf 'Installed %s\n' "$binary" >&2 # Positional parameters are free now; rebuild them as the setup arguments. set -- setup if [ -n "$exec_command" ]; then set -- "$@" --exec "$exec_command"; fi if [ -n "$agent_name" ]; then set -- "$@" --agent-name "$agent_name"; fi if [ -n "$network" ]; then set -- "$@" --env "$network"; fi if [ -n "$peer" ]; then set -- "$@" --connect "$peer"; fi if [ -n "$peer_name" ]; then set -- "$@" --name "$peer_name"; fi # Reports installed, activated, and verified. With --exec it fails unless all # three hold; without it, only the identity is set up. "$binary" "$@" } main "$@"