Created
December 29, 2025 08:12
-
-
Save devnamipress/1a51f45622b0dbbc65e9c92910c52552 to your computer and use it in GitHub Desktop.
Solana Installer
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # ============================================================ | |
| # Solana Development Environment Installer (Ubuntu/Debian) | |
| # Interactive, dialog-based CLI with step-by-step verification | |
| # ============================================================ | |
| # Exit handling: we want to control flow on failures, so avoid `set -e` | |
| set -u | |
| # ---------------------------- | |
| # Customizable ASCII header | |
| # ---------------------------- | |
| CUSTOM_HEADER="$(cat <<'ASCII' | |
| _____ _ ___ _ _ _ | |
| / ____| | | |__ \ | | | | | | |
| | (___ ___ | | __ _ _ __ __ _ ___ ) | ___ __| | _ __ | | | ___ _ __ | |
| \___ \ / _ \| |/ _` | '_ \ / _` |/ _ \ / / / _ \/ _` || '_ \| | |/ _ \| '_ \ | |
| ____) | (_) | | (_| | | | | (_| | __/ / /_| __/ (_| || |_) | | | (_) | | | | | |
| |_____/ \___/|_|\__,_|_| |_|\__, |\___||____|\___|\__,_|| .__/|_|_|\___/|_| |_| | |
| __/ | | | | |
| |___/ |_| | |
| Solana Installer | |
| ASCII | |
| )" | |
| # Dialog defaults | |
| DIALOG_BIN=${DIALOG_BIN:-dialog} | |
| DIALOG_TITLE=${DIALOG_TITLE:-"Solana Installer"} | |
| DIALOG_HEIGHT=${DIALOG_HEIGHT:-12} | |
| DIALOG_WIDTH=${DIALOG_WIDTH:-70} | |
| # Logs | |
| LOG_DIR="$(mktemp -d -t solana-install-XXXXXX)" | |
| RUST_LOG="$LOG_DIR/rust.log" | |
| SOLANA_LOG="$LOG_DIR/solana.log" | |
| ANCHOR_LOG="$LOG_DIR/anchor.log" | |
| SURFPOOL_LOG="$LOG_DIR/surfpool.log" | |
| NODE_LOG="$LOG_DIR/node.log" | |
| VERIFY_LOG="$LOG_DIR/verify.log" | |
| # ------------- | |
| # Utilities | |
| # ------------- | |
| cleanup() { | |
| rm -rf "$LOG_DIR" 2>/dev/null || true | |
| clear | |
| } | |
| trap cleanup EXIT | |
| have_cmd() { command -v "$1" >/dev/null 2>&1; } | |
| dialog_msg() { | |
| "$DIALOG_BIN" --backtitle "$DIALOG_TITLE" --msgbox "$1" "$DIALOG_HEIGHT" "$DIALOG_WIDTH" | |
| } | |
| dialog_info() { | |
| "$DIALOG_BIN" --backtitle "$DIALOG_TITLE" --infobox "$1" "$DIALOG_HEIGHT" "$DIALOG_WIDTH" | |
| sleep 2 | |
| } | |
| dialog_yesno() { | |
| # Returns 0 on Yes, 1 on No, 255 on Cancel/Esc | |
| "$DIALOG_BIN" --backtitle "$DIALOG_TITLE" --yesno "$1" "$DIALOG_HEIGHT" "$DIALOG_WIDTH" | |
| return $? | |
| } | |
| dialog_textbox() { | |
| # $1 = file path | |
| "$DIALOG_BIN" --backtitle "$DIALOG_TITLE" --textbox "$1" 20 "$DIALOG_WIDTH" | |
| } | |
| show_header() { | |
| printf "%s\n" "$CUSTOM_HEADER" >"$LOG_DIR/header.txt" | |
| "$DIALOG_BIN" --backtitle "$DIALOG_TITLE" --title "Welcome" --textbox "$LOG_DIR/header.txt" 15 "$DIALOG_WIDTH" | |
| } | |
| confirm_exit_on_cancel() { | |
| local code="${1:-255}" | |
| if [ "$code" -eq 255 ]; then | |
| dialog_yesno "You pressed Cancel. Do you want to exit the installer?" | |
| if [ $? -eq 0 ]; then | |
| dialog_msg "Exiting installer. Goodbye!" | |
| exit 1 | |
| fi | |
| fi | |
| } | |
| require_internet() { | |
| if ! curl -Is --max-time 5 https://solana.com >/dev/null 2>&1; then | |
| dialog_msg "No internet connection detected. Please connect and rerun." | |
| exit 1 | |
| fi | |
| } | |
| ensure_dialog_installed() { | |
| if have_cmd "$DIALOG_BIN"; then | |
| return | |
| fi | |
| echo "dialog not found. Installing via apt..." | |
| sudo apt update && sudo apt install -y dialog || { | |
| echo "Failed to install dialog" | |
| exit 1 | |
| } | |
| } | |
| # ----------------------------- | |
| # Package Descriptions (short) | |
| # ----------------------------- | |
| desc_rust="Rust is required to build and install developer tools like Anchor and Surfpool CLI." | |
| desc_solana="Solana CLI lets you interact with Solana clusters, manage keys, and deploy programs." | |
| desc_anchor="Anchor CLI streamlines Solana program development, build flows, and IDL management." | |
| desc_surfpool="Surfpool CLI provides surfpool tooling; installed via Cargo as a developer utility." | |
| desc_node="Node.js and Yarn are needed for JavaScript tooling and Anchor TypeScript workflows." | |
| # ----------------------------- | |
| # Version Checks | |
| # ----------------------------- | |
| check_rust() { rustc --version >/dev/null 2>&1; } | |
| check_solana() { solana --version >/dev/null 2>&1; } | |
| check_anchor() { anchor --version >/dev/null 2>&1; } | |
| check_surfpool() { surfpool --version >/dev/null 2>&1; } | |
| check_node() { node --version >/dev/null 2>&1 && yarn --version >/dev/null 2>&1; } | |
| # ----------------------------- | |
| # Installers | |
| # ----------------------------- | |
| install_rust() { | |
| dialog_info "Installing Rust... This may take a few minutes." | |
| { | |
| curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y | |
| # Source Cargo environment for current session | |
| if [ -f "$HOME/.cargo/env" ]; then | |
| # shellcheck source=/dev/null | |
| . "$HOME/.cargo/env" | |
| fi | |
| # Persist PATH updates if needed | |
| if ! grep -q 'cargo/env' "$HOME/.bashrc" 2>/dev/null; then | |
| echo '. "$HOME/.cargo/env"' >> "$HOME/.bashrc" | |
| fi | |
| } >"$RUST_LOG" 2>&1 | |
| } | |
| install_solana() { | |
| dialog_info "Installing Solana CLI... This may take a few minutes." | |
| { | |
| sh -c "$(curl -sSfL https://release.solana.com/stable/install)" | |
| } >"$SOLANA_LOG" 2>&1 | |
| } | |
| install_anchor() { | |
| dialog_info "Installing Anchor CLI... This may take a few minutes." | |
| { | |
| # Ensure Cargo is available (Rust installed) | |
| if ! have_cmd cargo; then | |
| echo "cargo not found; Rust must be installed first." >&2 | |
| exit 1 | |
| fi | |
| cargo install --git https://github.com/coral-xyz/anchor anchor-cli --locked | |
| } >"$ANCHOR_LOG" 2>&1 | |
| } | |
| install_surfpool() { | |
| dialog_info "Installing Surfpool CLI... This may take a few minutes." | |
| { | |
| if ! have_cmd cargo; then | |
| echo "cargo not found; Rust must be installed first." >&2 | |
| exit 1 | |
| fi | |
| cargo install surfpool-cli | |
| } >"$SURFPOOL_LOG" 2>&1 | |
| } | |
| install_node_yarn() { | |
| dialog_info "Installing Node.js, npm, and Yarn... This may take a few minutes." | |
| { | |
| sudo apt update | |
| sudo apt install -y nodejs npm | |
| sudo npm install -g yarn | |
| } >"$NODE_LOG" 2>&1 | |
| } | |
| verify_all() { | |
| { | |
| echo "Verification Output:" | |
| echo "--------------------" | |
| echo | |
| echo "rustc --version:" | |
| rustc --version || echo "rustc not found" | |
| echo | |
| echo "solana --version:" | |
| solana --version || echo "solana not found" | |
| echo | |
| echo "anchor --version:" | |
| anchor --version || echo "anchor not found" | |
| echo | |
| echo "surfpool --version:" | |
| surfpool --version || echo "surfpool not found" | |
| echo | |
| echo "node --version:" | |
| node --version || echo "node not found" | |
| echo | |
| echo "yarn --version:" | |
| yarn --version || echo "yarn not found" | |
| } >"$VERIFY_LOG" 2>&1 | |
| dialog_textbox "$VERIFY_LOG" | |
| } | |
| # ----------------------------- | |
| # Flow Control | |
| # ----------------------------- | |
| main() { | |
| # Ensure dialog is available before using it | |
| ensure_dialog_installed | |
| require_internet | |
| show_header | |
| # Inform about potential sudo prompts | |
| dialog_msg "Some installations require sudo. If prompted, please enter your password in the terminal. Press OK to continue." | |
| # Rust | |
| if check_rust; then | |
| dialog_msg "Package Rust is already installed. Skipping." | |
| else | |
| dialog_msg "$desc_rust" | |
| dialog_yesno "Do you want to install Rust? (Yes/No)" | |
| rc=$? | |
| confirm_exit_on_cancel "$rc" | |
| if [ "$rc" -eq 0 ]; then | |
| install_rust | |
| if check_rust; then | |
| dialog_msg "Rust installed successfully." | |
| else | |
| dialog_msg "Rust installation failed. Please review logs:\n$RUST_LOG" | |
| dialog_textbox "$RUST_LOG" | |
| fi | |
| else | |
| dialog_msg "Skipped Rust installation." | |
| fi | |
| fi | |
| # Solana CLI | |
| if check_solana; then | |
| dialog_msg "Package Solana CLI is already installed. Skipping." | |
| else | |
| dialog_msg "$desc_solana" | |
| dialog_yesno "Do you want to install Solana CLI? (Yes/No)" | |
| rc=$? | |
| confirm_exit_on_cancel "$rc" | |
| if [ "$rc" -eq 0 ]; then | |
| install_solana | |
| if check_solana; then | |
| dialog_msg "Solana CLI installed successfully." | |
| else | |
| dialog_msg "Solana CLI installation failed. Please review logs:\n$SOLANA_LOG" | |
| dialog_textbox "$SOLANA_LOG" | |
| fi | |
| else | |
| dialog_msg "Skipped Solana CLI installation." | |
| fi | |
| fi | |
| # Anchor CLI | |
| if check_anchor; then | |
| dialog_msg "Package Anchor CLI is already installed. Skipping." | |
| else | |
| dialog_msg "$desc_anchor" | |
| dialog_yesno "Do you want to install Anchor CLI? (Yes/No)" | |
| rc=$? | |
| confirm_exit_on_cancel "$rc" | |
| if [ "$rc" -eq 0 ]; then | |
| install_anchor | |
| if check_anchor; then | |
| dialog_msg "Anchor CLI installed successfully." | |
| else | |
| dialog_msg "Anchor CLI installation failed. Please review logs:\n$ANCHOR_LOG" | |
| dialog_textbox "$ANCHOR_LOG" | |
| fi | |
| else | |
| dialog_msg "Skipped Anchor CLI installation." | |
| fi | |
| fi | |
| # Surfpool CLI | |
| if check_surfpool; then | |
| dialog_msg "Package Surfpool CLI is already installed. Skipping." | |
| else | |
| dialog_msg "$desc_surfpool" | |
| dialog_yesno "Do you want to install Surfpool CLI? (Yes/No)" | |
| rc=$? | |
| confirm_exit_on_cancel "$rc" | |
| if [ "$rc" -eq 0 ]; then | |
| install_surfpool | |
| if check_surfpool; then | |
| dialog_msg "Surfpool CLI installed successfully." | |
| else | |
| dialog_msg "Surfpool CLI installation failed. Please review logs:\n$SURFPOOL_LOG" | |
| dialog_textbox "$SURFPOOL_LOG" | |
| fi | |
| else | |
| dialog_msg "Skipped Surfpool CLI installation." | |
| fi | |
| fi | |
| # Node.js & Yarn | |
| if check_node; then | |
| dialog_msg "Packages Node.js & Yarn are already installed. Skipping." | |
| else | |
| dialog_msg "$desc_node" | |
| dialog_yesno "Do you want to install Node.js & Yarn? (Yes/No)" | |
| rc=$? | |
| confirm_exit_on_cancel "$rc" | |
| if [ "$rc" -eq 0 ]; then | |
| install_node_yarn | |
| if check_node; then | |
| dialog_msg "Node.js & Yarn installed successfully." | |
| else | |
| dialog_msg "Node.js/Yarn installation failed. Please review logs:\n$NODE_LOG" | |
| dialog_textbox "$NODE_LOG" | |
| fi | |
| else | |
| dialog_msg "Skipped Node.js & Yarn installation." | |
| fi | |
| fi | |
| # Final verification | |
| verify_all | |
| # Summarize success/failure | |
| if check_rust && check_solana && check_anchor && check_surfpool && check_node; then | |
| dialog_msg "All tools installed and verified successfully!" | |
| else | |
| dialog_msg "Some verifications failed. Please review logs and consider rerunning the installer." | |
| fi | |
| } | |
| main "$@" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment