Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added install script #71

Merged
merged 7 commits into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@ Spaces are sovereign Bitcoin identities. They leverage the existing infrastructu

## Quick Start

Check out the [documentation](https://docs.spacesprotocol.org)
Paste the following into your terminal to install the latest version of Spaces:
```bash
curl --proto '=https' --tlsv1.2 -sSf https://install.spacesprotocol.org | sh
```


## Development setup on testnet4

Expand Down Expand Up @@ -66,13 +70,19 @@ spaced --chain testnet4 --bitcoin-rpc-user testnet4 --bitcoin-rpc-password testn

## Project Structure


| Package | Requires std | Description |
|----------|-----------------|-------------------------------------------------------------------------------------------------|
| client | Yes | Bitcoin consensus client and wallet service |
| wallet | Yes (no-std WIP) | Wallet library for building spaces transactions |
| protocol | No | Protocol consensus library |
| veritas | No | Stateless verifier library for mobile and other resource constrained devices with wasm support. |

## Documentation

Visit [docs](https://docs.spacesprotocol.org/) to get more information about Spaces protocol.


## License

Spaces is released under the terms of the MIT license. See LICENSE for more information or see https://opensource.org/licenses/MIT.
Spaces is released under the terms of the MIT license. See LICENSE for more information or see https://opensource.org/licenses/MIT.
268 changes: 268 additions & 0 deletions install.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,268 @@
#!/usr/bin/env sh
set -eu
(set -o pipefail 2>/dev/null) && set -o pipefail

help() {
cat <<'EOF'
Install spaces binaries (spaced and space-cli) from GitHub releases.

USAGE:
install.sh [options]

FLAGS:
-h, --help Display this message
-f, --force Force overwriting existing binaries
-v, --verbose Show detailed output

OPTIONS:
--tag VERSION Specific version to install (e.g., 0.0.6a), defaults to latest release
--to LOCATION Where to install the binaries (default: auto-detected based on OS)
For macOS: ~/.local/bin if exists, else ~/bin
For Linux: ~/.local/bin

NOTES:
The script will automatically choose an appropriate user-writable location.
The chosen directory will be added to your PATH if needed.
EOF
}

say() {
echo "install: $*" >&2
}

err() {
if [ -n "${td-}" ]; then
rm -rf "$td"
fi
say "error: $*"
say "run './install.sh --help' to see available options"
exit 1
}

need() {
if ! command -v "$1" > /dev/null 2>&1; then
err "need $1 (command not found)"
fi
}

add_to_path() {
local install_dir="$1"
local shell_rc
local reload_needed=false

# Detect shell configuration file based on $SHELL environment variable
if [[ "$SHELL" == */zsh ]]; then
shell_rc="$HOME/.zshrc"
shell_type="zsh"
else
shell_type="bash"
shell_rc="$HOME/.bashrc"
[ "$(uname -s)" = "Darwin" ] && shell_rc="$HOME/.bash_profile"
fi

if ! echo "$PATH" | tr ':' '\n' | grep -Fq "$install_dir"; then
say "Adding $install_dir to PATH in $shell_rc"
echo "export PATH=\"$install_dir:\$PATH\"" >> "$shell_rc"
reload_needed=true
fi

# Return whether reload is needed
[ "$reload_needed" = true ] && echo "reload" || echo "noreload"
}

determine_install_dir() {
local os="$1"
local specified_dir="$2"
local install_dir

if [ -n "$specified_dir" ]; then
install_dir="$specified_dir"
else
case "$os" in
darwin)
if [ -d "$HOME/.local/bin" ]; then
install_dir="$HOME/.local/bin"
else
install_dir="$HOME/bin"
fi
;;
linux)
install_dir="$HOME/.local/bin"
;;
*)
err "unsupported operating system: $os"
;;
esac
fi

# Create directory if it doesn't exist
if [ ! -d "$install_dir" ]; then
mkdir -p "$install_dir" || err "failed to create $install_dir"
fi

echo "$install_dir"
}

download() {
url="$1"
output="$2"
if command -v curl > /dev/null; then
if [ "$output" = "-" ]; then
curl --proto =https --tlsv1.2 -sSfL "$url"
else
curl --proto =https --tlsv1.2 -sSfL "$url" -o "$output"
fi
else
wget --https-only --secure-protocol=TLSv1_2 --quiet "$url" -O "$output"
fi
}

# Initialize default values
force=false
verbose=false
dest=""
tag=""
td=""

# Process command line arguments
while test $# -gt 0; do
case $1 in
--force | -f)
force=true
;;
--help | -h)
help
exit 0
;;
--verbose | -v)
verbose=true
;;
--tag)
tag="$2"
shift
;;
--to)
dest="$2"
shift
;;
*)
say "error: unrecognized argument '$1'"
help
exit 1
;;
esac
shift
done

# Check for required commands
command -v curl > /dev/null 2>&1 || command -v wget > /dev/null 2>&1 || err "need wget or curl"
need mktemp
need tar

# Detect OS and architecture
os=$(uname -s | tr '[:upper:]' '[:lower:]')
arch=$(uname -m)

# Map architecture to match release files
case "$arch" in
x86_64) arch="x86_64" ;;
aarch64|arm64) arch="arm64" ;;
*) err "unsupported architecture: $arch" ;;
esac

# Determine installation directory
dest=$(determine_install_dir "$os" "$dest")
[ "$verbose" = true ] && say "installing to: $dest"

# Get latest version if not specified
if [ -z "$tag" ]; then
[ "$verbose" = true ] && say "fetching latest release version..."
api_response=$(download "https://api.github.com/repos/spacesprotocol/spaces/releases/latest" - || echo "failed")
if [ "$api_response" = "failed" ]; then
err "could not fetch release information from GitHub"
fi

tag=$(echo "$api_response" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/')
if [ -z "$tag" ]; then
err "no releases found in the repository"
fi
fi

# Standardize tag format
tag_without_v="${tag#v}" # Remove 'v' prefix if present
check_tag="v$tag_without_v" # Add 'v' prefix for consistency

# Verify the tag exists
[ "$verbose" = true ] && say "verifying tag $check_tag exists..."
api_response=$(download "https://api.github.com/repos/spacesprotocol/spaces/releases/tags/$check_tag" - || echo "failed")
if [ "$api_response" = "failed" ] || echo "$api_response" | grep -q "Not Found"; then
err "release tag '$check_tag' not found"
fi

[ -z "$tag_without_v" ] && err "could not determine version to install"

[ "$verbose" = true ] && say "installing spaces version $check_tag"

# Create temporary directory
td=$(mktemp -d || mktemp -d -t tmp)
trap 'rm -rf "$td"' EXIT

# Construct download URL
download_url="https://github.com/spacesprotocol/spaces/releases/download/$check_tag/spaces-$check_tag-${os}-${arch}.tar.gz"

[ "$verbose" = true ] && say "downloading from: $download_url"

# Download and extract
download "$download_url" "$td/spaces.tar.gz" || err "download failed"
tar xzf "$td/spaces.tar.gz" -C "$td" || err "failed to extract archive"

# Install binaries
for binary in spaced space-cli; do
if [ -f "$dest/$binary" ] && [ "$force" = false ]; then
err "Found existing spaces executables at $dest. Use --force flag to overwrite"
fi

binary_path="$dest/$binary"
if ! find "$td" -type f -name "$binary" -exec cp {} "$binary_path" \; ; then
err "failed to copy $binary to $dest (permission denied)"
fi

if ! chmod 755 "$binary_path"; then
err "failed to set permissions on $binary (permission denied)"
fi

[ "$verbose" = true ] && say "installed $binary to $binary_path"
done

# Verify installation
for binary in spaced space-cli; do
if ! [ -x "$dest/$binary" ]; then
err "installation verification failed for $binary"
fi
done

# Add to PATH if needed and get reload status
reload_status=$(add_to_path "$dest")

# Final instructions
say "Successfully installed spaces $check_tag to $dest"

# Reload shell if needed
if [ "$reload_status" = "reload" ]; then
if [[ "$SHELL" == */zsh ]]; then
say "Please run 'source $HOME/.zshrc' to update your PATH"
else
if [ "$(uname -s)" = "Darwin" ]; then
say "Please run 'source $HOME/.bash_profile' to update your PATH"
else
say "Please run 'source $HOME/.bashrc' to update your PATH"
fi
fi
say "Or start a new terminal session to apply changes"
fi

# Show versions if verbose
if [ "$verbose" = true ]; then
say "installed version:"
"$dest/spaced" --version
fi
Loading