diff --git a/install-scripts/install-safe-chain.ps1 b/install-scripts/install-safe-chain.ps1 new file mode 100644 index 0000000..ac85891 --- /dev/null +++ b/install-scripts/install-safe-chain.ps1 @@ -0,0 +1,154 @@ +# Downloads and installs safe-chain for Windows +# Usage: iex (iwr "https://raw.githubusercontent.com/AikidoSec/safe-chain/main/install-scripts/install-safe-chain.ps1" -UseBasicParsing) + +param( + [string]$Version +) + +# Configuration +if (-not $Version) { + $Version = if ($env:SAFE_CHAIN_VERSION) { $env:SAFE_CHAIN_VERSION } else { "v0.0.2-binaries-beta" } +} + +$InstallDir = Join-Path $env:USERPROFILE ".safe-chain\bin" +$RepoUrl = "https://github.com/AikidoSec/safe-chain" + +# Ensure TLS 1.2 is enabled for downloads +[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 + +# Helper functions +function Write-Info { + param([string]$Message) + Write-Host "[INFO] $Message" -ForegroundColor Green +} + +function Write-Warn { + param([string]$Message) + Write-Host "[WARN] $Message" -ForegroundColor Yellow +} + +function Write-Error-Custom { + param([string]$Message) + Write-Host "[ERROR] $Message" -ForegroundColor Red + exit 1 +} + +# Detect architecture +function Get-Architecture { + $arch = $env:PROCESSOR_ARCHITECTURE + switch ($arch) { + "AMD64" { return "x64" } + "ARM64" { return "arm64" } + default { Write-Error-Custom "Unsupported architecture: $arch" } + } +} + +# Main installation +function Install-SafeChain { + Write-Info "Installing safe-chain $Version..." + + # Detect platform + $arch = Get-Architecture + $binaryName = "safe-chain-win-$arch.exe" + + Write-Info "Detected architecture: $arch" + + # Create installation directory + if (-not (Test-Path $InstallDir)) { + Write-Info "Creating installation directory: $InstallDir" + try { + New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null + } + catch { + Write-Error-Custom "Failed to create directory $InstallDir : $_" + } + } + + # Download binary + $downloadUrl = "$RepoUrl/releases/download/$Version/$binaryName" + $tempFile = Join-Path $InstallDir $binaryName + $finalFile = Join-Path $InstallDir "safe-chain.exe" + + Write-Info "Downloading from: $downloadUrl" + + try { + # Download with progress suppressed for cleaner output + $ProgressPreference = 'SilentlyContinue' + Invoke-WebRequest -Uri $downloadUrl -OutFile $tempFile -UseBasicParsing + $ProgressPreference = 'Continue' + } + catch { + Write-Error-Custom "Failed to download from $downloadUrl : $_" + } + + # Rename to final location + try { + Move-Item -Path $tempFile -Destination $finalFile -Force + } + catch { + Write-Error-Custom "Failed to move binary to $finalFile : $_" + } + + Write-Info "Binary installed to: $finalFile" + + # Check if directory is in PATH + $userPath = [Environment]::GetEnvironmentVariable("Path", "User") + if ($userPath -like "*$InstallDir*") { + Write-Info "Installation directory is already in PATH" + } + else { + Write-Warn "Installation directory is not in PATH" + Write-Host "" + Write-Warn "Would you like to add it to your PATH now? (Y/N)" + $response = Read-Host + + if ($response -eq "Y" -or $response -eq "y") { + try { + $newPath = "$userPath;$InstallDir" + [Environment]::SetEnvironmentVariable("Path", $newPath, "User") + Write-Info "Added to PATH. Please restart your terminal for changes to take effect." + } + catch { + Write-Warn "Failed to add to PATH automatically: $_" + Write-Warn "Please add the following directory to your PATH manually:" + Write-Host " $InstallDir" + } + } + else { + Write-Warn "Skipping PATH setup. Add the following directory to your PATH manually:" + Write-Host "" + Write-Host " $InstallDir" + Write-Host "" + } + } + + # Execute safe-chain setup + Write-Info "Running safe-chain setup..." + + try { + $env:Path = "$env:Path;$InstallDir" + & $finalFile setup + + if ($LASTEXITCODE -eq 0) { + Write-Info "✓ safe-chain installed and configured successfully!" + } + else { + Write-Warn "safe-chain was installed but setup encountered issues." + Write-Warn "You can run 'safe-chain setup' manually later." + } + } + catch { + Write-Warn "safe-chain was installed but setup encountered issues: $_" + Write-Warn "You can run 'safe-chain setup' manually later." + } + + Write-Info "Installation complete!" +} + +# Run installation +try { + Install-SafeChain +} +catch { + Write-Error-Custom "Installation failed: $_" +} diff --git a/install-scripts/install-safe-chain.sh b/install-scripts/install-safe-chain.sh new file mode 100755 index 0000000..37f3136 --- /dev/null +++ b/install-scripts/install-safe-chain.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +# Downloads and installs safe-chain, depending on the operating system and architecture +# Usage: curl -fsSL https://raw.githubusercontent.com/AikidoSec/safe-chain/main/install-scripts/install-safe-chain.sh | sh +# or: wget -qO- https://raw.githubusercontent.com/AikidoSec/safe-chain/main/install-scripts/install-safe-chain.sh | sh + +set -e # Exit on error + +# Configuration +VERSION="${SAFE_CHAIN_VERSION:-v0.0.2-binaries-beta}" +INSTALL_DIR="${HOME}/.safe-chain/bin" +REPO_URL="https://github.com/AikidoSec/safe-chain" + +# Colors for output +RED='\033[0;31m' +GREEN='\033[0;32m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Helper functions +info() { + printf "${GREEN}[INFO]${NC} %s\n" "$1" +} + +warn() { + printf "${YELLOW}[WARN]${NC} %s\n" "$1" +} + +error() { + printf "${RED}[ERROR]${NC} %s\n" "$1" >&2 + exit 1 +} + +# Detect OS +detect_os() { + case "$(uname -s)" in + Linux*) echo "linux" ;; + Darwin*) echo "macos" ;; + *) error "Unsupported operating system: $(uname -s)" ;; + esac +} + +# Detect architecture +detect_arch() { + case "$(uname -m)" in + x86_64|amd64) echo "x64" ;; + aarch64|arm64) echo "arm64" ;; + *) error "Unsupported architecture: $(uname -m)" ;; + esac +} + +# Check if command exists +command_exists() { + command -v "$1" >/dev/null 2>&1 +} + +# Download file +download() { + url="$1" + dest="$2" + + if command_exists curl; then + curl -fsSL "$url" -o "$dest" || error "Failed to download from $url" + elif command_exists wget; then + wget -q "$url" -O "$dest" || error "Failed to download from $url" + else + error "Neither curl nor wget found. Please install one of them." + fi +} + +# Main installation +main() { + info "Installing safe-chain ${VERSION}..." + + # Detect platform + OS=$(detect_os) + ARCH=$(detect_arch) + BINARY_NAME="safe-chain-${OS}-${ARCH}" + + info "Detected platform: ${OS}-${ARCH}" + + # Create installation directory + if [ ! -d "$INSTALL_DIR" ]; then + info "Creating installation directory: $INSTALL_DIR" + mkdir -p "$INSTALL_DIR" || error "Failed to create directory $INSTALL_DIR" + fi + + # Download binary + DOWNLOAD_URL="${REPO_URL}/releases/download/${VERSION}/${BINARY_NAME}" + TEMP_FILE="${INSTALL_DIR}/${BINARY_NAME}" + FINAL_FILE="${INSTALL_DIR}/safe-chain" + + info "Downloading from: $DOWNLOAD_URL" + download "$DOWNLOAD_URL" "$TEMP_FILE" + + # Rename and make executable + mv "$TEMP_FILE" "$FINAL_FILE" || error "Failed to move binary to $FINAL_FILE" + chmod +x "$FINAL_FILE" || error "Failed to make binary executable" + + info "Binary installed to: $FINAL_FILE" + + # Check if directory is in PATH + case ":$PATH:" in + *":$INSTALL_DIR:"*) + info "Installation directory is already in PATH" + ;; + *) + warn "Installation directory is not in PATH" + warn "Add the following line to your shell profile (~/.bashrc, ~/.zshrc, etc.):" + printf "\n export PATH=\"\$PATH:${INSTALL_DIR}\"\n\n" + ;; + esac + + # Execute safe-chain setup + info "Running safe-chain setup..." + if "$FINAL_FILE" setup; then + info "✓ safe-chain installed and configured successfully!" + else + warn "safe-chain was installed but setup encountered issues." + warn "You can run 'safe-chain setup' manually later." + fi + + info "Installation complete!" +} + +main