diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f211ec7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,31 @@ +# Nix build outputs +result* +.direnv/ + +# Development environments +.vscode/ +.cursor/ + +# Rust/Cargo +target/ +Cargo.lock +**/*.rs.bk +*.pdb + +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# Temporary files +*.tmp +*.temp +*.log + +# General +*.backup +*.bak +*.orig + +# Working +work/ \ No newline at end of file diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 7f4686a..bf3a886 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -5,6 +5,7 @@ - [Build Valence Contracts](./guides/build-valence-contracts.md) - [Upload Contracts](./guides/upload-contracts.md) - [ZK Development](./guides/zk-development.md) + - [Solana Development](./guides/solana-development.md) - [Flake Modules Reference](./reference/flake-modules/index.md) - [Upload Contracts Options](./reference/flake-modules/upload-contracts.md) - [Valence Contracts Options](./reference/flake-modules/valence-contracts.md) diff --git a/docs/arch.md b/docs/arch.md index 200cbba..669759a 100644 --- a/docs/arch.md +++ b/docs/arch.md @@ -32,6 +32,11 @@ The system includes packages for various blockchain-related tools: - Manages specific contract packages for the Valence Protocol - Supports multiple contract versions (v0.1.1, v0.1.2, and main) +- **Solana Tools** (`packages/solana-tools.nix`): + - Provides complete Solana development environment including CLI, Anchor framework, and platform tools + - Supports SBF (Solana Berkeley Format) program compilation + - Includes Solana CLI (v2.0.22), Anchor CLI (v0.31.1), and Platform Tools (v1.48) + ### 3. Flake Modules The flake modules extend the functionality of the system: @@ -51,6 +56,15 @@ Additional tooling to support the blockchain simulation environment: - Tools for building Valence Protocol contracts from source - Integrates with the Rust toolchain via crane and rust-overlay +### 5. Templates + +Development environment templates for different blockchain platforms: + +- **Solana Development** (`templates/solana-development/`): + - Ready-to-use template for Solana development projects + - Includes complete Solana toolchain with Anchor framework + - Supports SBF program compilation and testing + ## Architecture ```mermaid @@ -260,4 +274,6 @@ Zero.nix can be used to simulate various multi-chain scenarios, such as: - Validating IBC protocol implementations - Developing and testing cross-chain applications - Benchmarking relayer performance under different network conditions -- Simulating complex multi-chain application workflows \ No newline at end of file +- Simulating complex multi-chain application workflows +- Developing Solana programs with SBF compilation support +- Testing Solana smart contracts using the Anchor framework \ No newline at end of file diff --git a/docs/guides/index.md b/docs/guides/index.md index a091e00..917c2f3 100644 --- a/docs/guides/index.md +++ b/docs/guides/index.md @@ -2,4 +2,5 @@ - [Build Valence Contracts](./build-valence-contracts.md) - [Upload Contracts](./upload-contracts.md) - [ZK Development](./zk-development.md) +- [Solana Development](./solana-development.md) diff --git a/docs/guides/solana-development.md b/docs/guides/solana-development.md new file mode 100644 index 0000000..a978961 --- /dev/null +++ b/docs/guides/solana-development.md @@ -0,0 +1,269 @@ +# Solana Development + +This document covers how to use zero.nix for Solana development, including setup of the Solana CLI, Anchor framework, and platform tools. + +## Overview + +Zero.nix provides a complete Solana development environment with: +- **Solana CLI** (v2.0.22) - Core Solana command-line tools +- **Anchor CLI** (v0.31.1) - Solana development framework +- **Platform Tools** (v1.48) - Rust compiler and LLVM tools optimized for Solana +- **SBF compilation** - Support for Solana Berkeley Format programs + +## Quick Start + +### Using the Template + +Create a new Solana project using the zero.nix template: + +```bash +nix flake new -t github:timewave-computer/zero.nix#solana-dev my-solana-project +cd my-solana-project +nix develop +``` + +### Manual Setup + +Add zero.nix to your existing Solana project: + +```nix +{ + description = "My Solana project"; + + inputs = { + zero-nix.url = "github:timewave-computer/zero.nix"; + }; + + outputs = { self, zero-nix }: + zero-nix.lib.mkFlake { + inherit self; + src = ./.; + }; +} +``` + +## Development Environment + +### Entering the Development Environment + +```bash +nix develop +``` + +This provides access to: +- `solana` - Solana CLI tools +- `anchor` - Anchor framework CLI +- `cargo-build-sbf` - SBF program compilation +- `setup-solana` - Environment initialization script + +### Environment Setup + +Initialize the Solana development environment: + +```bash +setup-solana +``` + +This script: +- Creates necessary cache directories +- Verifies platform tools installation +- Sets up proper permissions + +## Working with Anchor + +### Creating a New Anchor Project + +```bash +anchor init my-project +cd my-project +``` + +### Building Anchor Programs + +```bash +# Build the program +anchor build + +# Build with SBF compilation +cargo-build-sbf +``` + +### Testing Anchor Programs + +```bash +# Run tests +anchor test + +# Run tests with local validator +anchor test --skip-local-validator +``` + +## Solana CLI Usage + +### Configuration + +```bash +# Configure Solana CLI for devnet +solana config set --url https://api.devnet.solana.com + +# Generate a new keypair +solana-keygen new + +# Check balance +solana balance +``` + +### Local Development + +```bash +# Start local test validator +solana-test-validator + +# Deploy to local cluster +solana program deploy target/deploy/my_program.so +``` + +## Platform Tools + +The zero.nix Solana environment includes platform tools that provide: +- **Rust toolchain** - Optimized for Solana development +- **LLVM tools** - Required for SBF compilation +- **Cargo extensions** - SBF-specific build tools + +### Platform Tools Environment + +Platform tools are automatically configured with: +- `PLATFORM_TOOLS_DIR` - Points to platform tools directory +- `SBF_SDK_PATH` - SDK path for SBF compilation +- `PATH` - Extended to include platform tools + +## SBF Program Development + +### Building SBF Programs + +```bash +# Build SBF programs directly +cargo-build-sbf --manifest-path=Cargo.toml + +# Build with Anchor (recommended) +anchor build +``` + +### SBF Compilation Environment + +The environment automatically configures: +- Rust toolchain compatible with Solana +- LLVM tools for SBF target compilation +- Proper linker settings for macOS + +## Available Tools + +### Core Tools + +- **solana** - Main Solana CLI +- **solana-keygen** - Key generation and management +- **solana-test-validator** - Local test validator +- **anchor** - Anchor framework CLI +- **cargo-build-sbf** - SBF program compilation + +### Development Tools + +- **rustc** - Rust compiler +- **cargo** - Rust package manager +- **rust-analyzer** - Rust language server +- **nodejs** - JavaScript runtime +- **python3** - Python interpreter + +## Configuration + +### Environment Variables + +The development environment automatically sets: + +```bash +MACOSX_DEPLOYMENT_TARGET=11.0 # macOS deployment target +SOLANA_INSTALL_DIR=$HOME/.cache/solana # Solana cache directory +ANCHOR_VERSION=0.31.1 # Anchor version +SOLANA_VERSION=2.0.22 # Solana version +RUST_BACKTRACE=1 # Enable Rust backtraces +PLATFORM_TOOLS_DIR= # Platform tools directory (avoids redownloading) +SBF_SDK_PATH= # SBF SDK path for compilation +PROTOC=/bin/protoc # Protocol buffers compiler +CARGO_HOME=$HOME/.cache/solana/v1.48/cargo # Cargo cache directory (prevents redownloading) +RUSTUP_HOME=$HOME/.cache/solana/v1.48/rustup # Rustup cache directory (prevents redownloading) +``` + +These environment variables ensure that: +- Platform tools are not redownloaded on each build +- SBF compilation uses the pre-installed tools +- Proper macOS deployment target is set +- Debugging information is available +- Cargo and rustup use cached platform tools configuration + +### Custom Configuration + +Extend the development environment in your `flake.nix`: + +```nix +{ + outputs = { self, zero-nix }: + zero-nix.lib.mkFlake { + inherit self; + src = ./.; + + devShells.default = zero-nix.devShells.default.overrideAttrs (oldAttrs: { + shellHook = (oldAttrs.shellHook or "") + '' + # Custom solana configuration + solana config set --url https://api.mainnet-beta.solana.com + + # Project-specific setup + echo "My Solana project initialized" + ''; + }); + }; +} +``` + +### Debug Mode + +Enable verbose output for debugging: + +```bash +RUST_BACKTRACE=full anchor build +``` + +## Integration with Existing Projects + +### Adding to Existing Rust Projects + +Add zero.nix to your `flake.nix`: + +```nix +{ + inputs = { + zero-nix.url = "github:timewave-computer/zero.nix"; + }; + + outputs = { self, zero-nix }: { + devShells.default = zero-nix.devShells.default.overrideAttrs (oldAttrs: { + buildInputs = (oldAttrs.buildInputs or []) ++ (with zero-nix.legacyPackages.${system}; [ + solana-tools + # Add your existing tools here + ]); + }); + }; +} +``` + +## Documentation + +- [Anchor Book](https://book.anchor-lang.com/) +- [Solana program development](https://docs.solana.com/developing/programming-model/overview) +- [Solana CLI reference](https://docs.solana.com/cli) + +## Version Information + +- **Solana CLI**: v2.0.22 +- **Anchor CLI**: v0.31.1 +- **Platform Tools**: v1.48 +- **Rust**: Compatible with Solana (via platform tools) \ No newline at end of file diff --git a/packages/default.nix b/packages/default.nix index 87bf224..26d83b5 100644 --- a/packages/default.nix +++ b/packages/default.nix @@ -1,15 +1,116 @@ +# Purpose: Main packages definition file for zero.nix +{ inputs, ... }: { imports = [ ./valence-contracts.nix ]; - perSystem = { pkgs, config, ... }: { + + perSystem = { pkgs, config, lib, system, ... }: + let + # Import Solana tools + solana-tools = pkgs.callPackage ./solana-tools.nix { + inherit inputs; + }; + + # Solana version constants for shellHook + sol-version = "2.0.22"; + anchor-version = "0.31.1"; + platform-tools-version = "1.48"; + + # Common environment variables for development + commonEnv = { + SOURCE_DATE_EPOCH = "1686858254"; # Fixed value for reproducible builds + }; + in { packages = { + # Existing packages upload-contract = pkgs.callPackage ./upload-contract {}; local-ic = pkgs.callPackage ./local-ic.nix {}; sp1-rust = pkgs.callPackage ./sp1-rust.nix {}; sp1 = pkgs.callPackage ./sp1.nix { inherit (config.packages) sp1-rust; }; + + # Solana packages from solana-tools.nix + inherit (solana-tools) solana-node anchor setup-solana nightly-rust anchor-wrapper solana-tools; + }; + + devShells.default = pkgs.mkShell { + name = "zero-nix-dev"; + buildInputs = with pkgs; [ + # Basic development tools + git + curl + jq + + # Nix tools + nix-prefetch-git + + # Build tools + pkg-config + + # Include our custom packages + config.packages.upload-contract + + # Solana development tools + config.packages.solana-tools + + # Rust toolchain for Solana development + pkgs.rustc + pkgs.cargo + pkgs.rust-analyzer + + # Additional tools for Solana development + nodejs + yarn + python3 + protobuf + ]; + + shellHook = '' + echo "Welcome to zero.nix development environment" + echo "Available packages: upload-contract, local-ic, sp1-rust, sp1" + echo "Solana tools: solana-node, anchor, setup-solana, nightly-rust" + echo "" + echo "Run 'setup-solana' to initialize Solana development environment" + echo "Solana CLI version: ${sol-version}" + echo "Anchor CLI version: ${anchor-version}" + echo "Platform tools version: ${platform-tools-version}" + echo "Nightly Rust for IDL generation: available" + echo "" + + # Set up platform tools environment to avoid redownloading + export PLATFORM_TOOLS_DIR=${config.packages.solana-node}/platform-tools + export SBF_SDK_PATH=${config.packages.solana-node}/platform-tools + export PATH="${config.packages.solana-node}/platform-tools/rust/bin:${config.packages.solana-node}/bin:$PATH" + + # Set Solana environment variables + export SOURCE_DATE_EPOCH="${commonEnv.SOURCE_DATE_EPOCH}" + export SOLANA_INSTALL_DIR="$HOME/.cache/solana" + export RUST_BACKTRACE="1" + export PROTOC=${pkgs.protobuf}/bin/protoc + + # Platform-specific environment variables + ${lib.optionalString pkgs.stdenv.isDarwin '' + export MACOSX_DEPLOYMENT_TARGET="11.0" + export CARGO_BUILD_TARGET="${if pkgs.stdenv.isAarch64 then "aarch64" else "x86_64"}-apple-darwin" + export RUSTFLAGS="-C link-arg=-undefined -C link-arg=dynamic_lookup" + ''} + ${lib.optionalString pkgs.stdenv.isLinux '' + export CARGO_BUILD_TARGET="${if pkgs.stdenv.isAarch64 then "aarch64" else "x86_64"}-unknown-linux-gnu" + ''} + + # Critical: Set cargo/rustup cache directories to prevent redownloading + export CARGO_HOME="$HOME/.cache/solana/v${platform-tools-version}/cargo" + export RUSTUP_HOME="$HOME/.cache/solana/v${platform-tools-version}/rustup" + + # Create cache directories + mkdir -p "$CARGO_HOME" "$RUSTUP_HOME" + mkdir -p "$SOLANA_INSTALL_DIR/releases" "$SOLANA_INSTALL_DIR/config" + + echo "Platform tools configured: $PLATFORM_TOOLS_DIR" + echo "SBF SDK path: $SBF_SDK_PATH" + ''; }; }; } diff --git a/packages/solana-tools.nix b/packages/solana-tools.nix new file mode 100644 index 0000000..a1375cd --- /dev/null +++ b/packages/solana-tools.nix @@ -0,0 +1,358 @@ +# Purpose: Solana development tools including CLI, Anchor, and platform tools for SBF compilation +{ pkgs, lib, inputs, ... }: + +let + # Apply rust-overlay to pkgs for rust-bin support + rustPkgs = pkgs.appendOverlays [ + inputs.rust-overlay.overlays.rust-overlay + ]; + + # Solana and Anchor versions - pinned for stability + sol-version = "2.0.22"; + anchor-version = "0.31.1"; + platform-tools-version = "1.48"; + + # macOS deployment target (used for all Darwin systems) + darwinDeploymentTarget = "11.0"; + + # Common environment variables for Solana development + commonEnv = { + SOURCE_DATE_EPOCH = "1686858254"; # Fixed value for reproducible builds + SOLANA_INSTALL_DIR = "$HOME/.cache/solana"; + ANCHOR_VERSION = anchor-version; + SOLANA_VERSION = sol-version; + RUST_BACKTRACE = "1"; + } // lib.optionalAttrs pkgs.stdenv.isDarwin { + MACOSX_DEPLOYMENT_TARGET = darwinDeploymentTarget; + }; + + # Nightly Rust environment specifically for IDL generation + nightly-rust = rustPkgs.rust-bin.nightly."2024-12-01".default.override { + extensions = [ "rust-src" "llvm-tools-preview" ]; + }; + + # Unified Solana node derivation including platform tools and CLI tools + solana-node = pkgs.stdenv.mkDerivation rec { + pname = "solana-node"; + version = sol-version; + + # Primary Solana CLI source + solana-src = pkgs.fetchurl { + url = "https://github.com/anza-xyz/agave/releases/download/v${version}/solana-release-${ + if pkgs.stdenv.isDarwin then + if pkgs.stdenv.isAarch64 then "aarch64-apple-darwin" else "x86_64-apple-darwin" + else + "x86_64-unknown-linux-gnu" + }.tar.bz2"; + sha256 = if pkgs.stdenv.isDarwin then + "sha256-upgxwAEvh11+IKVQ1FaZGlx8Z8Ps0CEScsbu4Hv3WH0=" # v2.0.22 macOS ARM64 hash + else + "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # TODO: Get correct Linux hash with: nix store prefetch-file --json https://github.com/anza-xyz/agave/releases/download/v2.0.22/solana-release-x86_64-unknown-linux-gnu.tar.bz2 + }; + + # Platform tools source + platform-tools-src = pkgs.fetchurl { + url = if pkgs.stdenv.isDarwin then + "https://github.com/anza-xyz/platform-tools/releases/download/v${platform-tools-version}/platform-tools-osx-aarch64.tar.bz2" + else + "https://github.com/anza-xyz/platform-tools/releases/download/v${platform-tools-version}/platform-tools-linux-x86_64.tar.bz2"; + sha256 = if pkgs.stdenv.isDarwin then + "sha256-eZ5M/O444icVXIP7IpT5b5SoQ9QuAcA1n7cSjiIW0t0=" # v1.48 macOS ARM64 hash + else + "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; # TODO: Get correct Linux hash with: nix store prefetch-file --json https://github.com/anza-xyz/platform-tools/releases/download/v1.48/platform-tools-linux-x86_64.tar.bz2 + }; + + nativeBuildInputs = with pkgs; [ + makeWrapper + ] ++ lib.optionals stdenv.isLinux [ + autoPatchelfHook + ] ++ lib.optionals stdenv.isDarwin [ + darwin.cctools + darwin.sigtool + ]; + + buildInputs = with pkgs; [ + stdenv.cc.cc.lib + zlib + openssl + libffi + ] ++ lib.optionals stdenv.isLinux [ + glibc + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; + + unpackPhase = '' + runHook preUnpack + + # Create separate directories for each source + mkdir -p solana-cli platform-tools + + # Extract Solana CLI + cd solana-cli + tar -xf ${solana-src} + cd .. + + # Extract platform tools + cd platform-tools + tar -xf ${platform-tools-src} + cd .. + + runHook postUnpack + ''; + + installPhase = '' + runHook preInstall + + mkdir -p $out/bin $out/lib $out/platform-tools + + # Install Solana CLI tools + if [ -d "solana-cli/solana-release/bin" ]; then + cp -r solana-cli/solana-release/bin/* $out/bin/ + elif [ -d "solana-cli/bin" ]; then + cp -r solana-cli/bin/* $out/bin/ + else + # Look for any directories with binaries + for dir in solana-cli/*/; do + if [ -d "$dir/bin" ]; then + cp -r "$dir/bin"/* $out/bin/ + break + fi + done + fi + + # Install platform tools + cp -r platform-tools/* $out/platform-tools/ + + # Make platform tools binaries available in PATH + if [ -d "$out/platform-tools/rust/bin" ]; then + for tool in $out/platform-tools/rust/bin/*; do + if [ -f "$tool" ] && [ -x "$tool" ]; then + tool_name=$(basename "$tool") + # Don't override main Solana CLI tools + if [ ! -f "$out/bin/$tool_name" ]; then + ln -sf "$tool" "$out/bin/$tool_name" + fi + fi + done + fi + + if [ -d "$out/platform-tools/llvm/bin" ]; then + for tool in $out/platform-tools/llvm/bin/*; do + if [ -f "$tool" ] && [ -x "$tool" ]; then + tool_name=$(basename "$tool") + # Don't override main Solana CLI tools + if [ ! -f "$out/bin/$tool_name" ]; then + ln -sf "$tool" "$out/bin/$tool_name" + fi + fi + done + fi + + # Ensure all binaries are executable + find $out -type f -executable -exec chmod +x {} \; 2>/dev/null || true + + # Fix broken symlinks + find $out -type l ! -exec test -e {} \; -delete 2>/dev/null || true + + # Create wrapper scripts for key tools + for tool in solana solana-keygen solana-test-validator; do + if [ -f "$out/bin/$tool" ]; then + # Backup original binary + mv "$out/bin/$tool" "$out/bin/.$tool-original" + + # Create wrapper script + cat > "$out/bin/$tool" << EOF +#!/bin/bash +export PLATFORM_TOOLS_DIR="$out/platform-tools" +export SBF_SDK_PATH="$out/platform-tools" +export PATH="$out/platform-tools/rust/bin:$out/platform-tools/llvm/bin:\$PATH" +exec "$out/bin/.$tool-original" "\$@" +EOF + chmod +x "$out/bin/$tool" + fi + done + + # Create special wrapper for cargo-build-sbf that bypasses platform tools installation + if [ -f "$out/bin/cargo-build-sbf" ]; then + # Backup original binary + mv "$out/bin/cargo-build-sbf" "$out/bin/.cargo-build-sbf-original" + + # Create wrapper script that uses cargo directly with SBF target + cat > "$out/bin/cargo-build-sbf" << EOF +#!/bin/bash +export PLATFORM_TOOLS_DIR="$out/platform-tools" +export SBF_SDK_PATH="$out/platform-tools" +export PATH="$out/platform-tools/rust/bin:$out/platform-tools/llvm/bin:\$PATH" + +# Handle both standalone cargo-build-sbf and cargo build-sbf subcommand usage +if [[ "\$1" == "build-sbf" ]]; then + # Called as cargo subcommand: cargo build-sbf [args] + # Remove the "build-sbf" argument and pass the rest + shift +fi + +# Use cargo directly with SBF target instead of cargo-build-sbf to avoid installation issues +# This bypasses the platform tools installation logic entirely +exec cargo build --release --target sbf-solana-solana "\$@" +EOF + chmod +x "$out/bin/cargo-build-sbf" + fi + + runHook postInstall + ''; + + meta = with pkgs.lib; { + description = "Complete Solana node with platform tools and CLI"; + homepage = "https://solana.com"; + license = licenses.asl20; + platforms = [ "x86_64-linux" "x86_64-darwin" "aarch64-darwin" ]; + maintainers = [ ]; + }; + }; + + # Build anchor CLI from source with rust-overlay + anchor = pkgs.rustPlatform.buildRustPackage rec { + pname = "anchor-cli"; + version = anchor-version; + + src = pkgs.fetchFromGitHub { + owner = "coral-xyz"; + repo = "anchor"; + rev = "v${version}"; + hash = "sha256-pvD0v4y7DilqCrhT8iQnAj5kBxGQVqNvObJUBzFLqzA="; + fetchSubmodules = true; + }; + + useFetchCargoVendor = true; + cargoHash = "sha256-fjhLA+utQdgR75wg+/N4VwASW6+YBHglRPj14sPHmGA="; + + # Build the CLI package specifically + cargoBuildFlags = [ "--package" "anchor-cli" ]; + cargoTestFlags = [ "--package" "anchor-cli" ]; + + # Skip tests for faster builds + doCheck = false; + + nativeBuildInputs = with pkgs; [ + pkg-config + rustc + cargo + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.SystemConfiguration + ]; + + buildInputs = with pkgs; [ + openssl + libiconv + ] ++ lib.optionals stdenv.isLinux [ + libudev-zero + ] ++ lib.optionals stdenv.isDarwin [ + darwin.apple_sdk.frameworks.Security + darwin.apple_sdk.frameworks.CoreFoundation + darwin.apple_sdk.frameworks.CoreServices + ]; + + # Environment variables for building + OPENSSL_NO_VENDOR = "1"; + SOURCE_DATE_EPOCH = commonEnv.SOURCE_DATE_EPOCH; + + # Platform-specific environment variables + MACOSX_DEPLOYMENT_TARGET = lib.optionalString pkgs.stdenv.isDarwin darwinDeploymentTarget; + RUSTFLAGS = lib.optionalString pkgs.stdenv.isDarwin + "-C link-arg=-undefined -C link-arg=dynamic_lookup"; + + # Clean build without toolchain installation patches + postPatch = '' + # Remove any toolchain installation code that might interfere + find . -name "*.rs" -type f -exec sed -i 's/install_toolchain_if_needed.*;//g' {} \; + ''; + + meta = with pkgs.lib; { + description = "Solana Sealevel Framework CLI"; + homepage = "https://github.com/coral-xyz/anchor"; + license = licenses.asl20; + maintainers = [ ]; + platforms = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; + }; + }; + + # Setup script for Solana environment + setup-solana = pkgs.writeShellScriptBin "setup-solana" '' + set -e + + echo "Setting up Solana development environment..." + echo "Platform tools v${platform-tools-version} location: ${solana-node}" + echo "Solana CLI v${sol-version} location: ${solana-node}" + echo "Anchor CLI v${anchor-version} location: ${anchor}" + + # Create cache directories with proper permissions + SOLANA_CACHE_DIR="$HOME/.cache/solana" + mkdir -p "$SOLANA_CACHE_DIR/v${platform-tools-version}/cargo" "$SOLANA_CACHE_DIR/v${platform-tools-version}/rustup" + mkdir -p "$SOLANA_CACHE_DIR/releases" "$SOLANA_CACHE_DIR/config" + chmod -R 755 "$SOLANA_CACHE_DIR" + + echo "Solana development environment setup complete!" + ''; + + # Wrapper for anchor that uses platform tools and nightly rust for IDL generation + anchor-wrapper = pkgs.writeShellScriptBin "anchor" '' + set -e + + # Set up platform tools environment for SBF compilation + export PLATFORM_TOOLS_DIR=${solana-node}/platform-tools + export SBF_SDK_PATH=${solana-node}/platform-tools + export PATH="${solana-node}/platform-tools/rust/bin:${solana-node}/bin:$PATH" + + # Set required environment variables + export SOURCE_DATE_EPOCH="${commonEnv.SOURCE_DATE_EPOCH}" + export RUST_BACKTRACE=1 + export PROTOC=${pkgs.protobuf}/bin/protoc + + # Platform-specific environment variables + ${lib.optionalString pkgs.stdenv.isDarwin '' + export MACOSX_DEPLOYMENT_TARGET="${darwinDeploymentTarget}" + export CARGO_BUILD_TARGET="${if pkgs.stdenv.isAarch64 then "aarch64" else "x86_64"}-apple-darwin" + export RUSTFLAGS="-C link-arg=-undefined -C link-arg=dynamic_lookup" + ''} + ${lib.optionalString pkgs.stdenv.isLinux '' + export CARGO_BUILD_TARGET="${if pkgs.stdenv.isAarch64 then "aarch64" else "x86_64"}-unknown-linux-gnu" + ''} + + # Critical: Set cargo/rustup cache directories to prevent redownloading + export CARGO_HOME="$HOME/.cache/solana/v${platform-tools-version}/cargo" + export RUSTUP_HOME="$HOME/.cache/solana/v${platform-tools-version}/rustup" + + # Ensure cache directories exist + mkdir -p "$CARGO_HOME" "$RUSTUP_HOME" + + # Check if this is for IDL generation and use nightly rust + case " $@ " in + *" idl "*) + export PATH="${nightly-rust}/bin:${solana-node}/bin:$PATH" + export RUSTC="${nightly-rust}/bin/rustc" + export CARGO="${nightly-rust}/bin/cargo" + ;; + esac + + # Run anchor with platform tools environment + exec "${anchor}/bin/anchor" "$@" + ''; + +in { + # Individual packages + inherit solana-node anchor setup-solana nightly-rust; + anchor-wrapper = anchor-wrapper; + + # Combined solana development environment + solana-tools = pkgs.symlinkJoin { + name = "solana-tools"; + paths = [ + solana-node + anchor-wrapper + setup-solana + ]; + }; +} \ No newline at end of file diff --git a/templates/default.nix b/templates/default.nix index d4c11bf..1a53d04 100644 --- a/templates/default.nix +++ b/templates/default.nix @@ -18,5 +18,27 @@ in ${commonWelcome} ''; }; + + solana-dev = { + path = ./solana-development; + description = "Solana development environment"; + welcomeText = '' + # Solana development environment + ## Provided packages + - solana CLI (v2.0.22) + - anchor CLI (v0.31.1) + - platform tools (v1.48) + - cargo-build-sbf + - Rust toolchain + + ## Getting started + - Run 'nix develop' to enter the development environment + - Run 'setup-solana' to initialize Solana tools + - Create a new Anchor project with 'anchor init my-project' + - Build SBF programs with 'cargo-build-sbf' + + ${commonWelcome} + ''; + }; }; } diff --git a/templates/solana-development/flake.nix b/templates/solana-development/flake.nix new file mode 100644 index 0000000..d391e81 --- /dev/null +++ b/templates/solana-development/flake.nix @@ -0,0 +1,63 @@ +{ + description = "Solana development environment using zero.nix"; + + nixConfig.extra-experimental-features = "nix-command flakes"; + nixConfig.extra-substituters = "https://timewave.cachix.org"; + nixConfig.extra-trusted-public-keys = '' + colmena.cachix.org-1:7BzpDnjjH8ki2CT3f6GdOk7QAzPOl+1t3LvTLXqYcSg= + cosmos-nix.cachix.org-1:I9dmz4kn5+JExjPxOd9conCzQVHPl0Jo1Cdp6s+63d4= + nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs= + ''; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-24.11"; + + flake-parts.url = "github:hercules-ci/flake-parts"; + + devshell.url = "github:numtide/devshell"; + + zero-nix.url = "github:timewave-computer/zero.nix"; + }; + + outputs = { + self, + flake-parts, + ... + } @ inputs: + flake-parts.lib.mkFlake {inherit inputs;} { + imports = [ + inputs.devshell.flakeModule + ]; + + systems = ["x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin"]; + + perSystem = { + pkgs, + inputs', + ... + }: { + devshells.default = {pkgs, ...}: { + commands = [ + {package = inputs'.zero-nix.packages.solana-tools;} + {package = inputs'.zero-nix.packages.setup-solana;} + ]; + + devshell.startup.setup-solana = { + deps = []; + text = '' + echo "🌞 Solana development environment using zero.nix" + echo "Available tools:" + echo " - solana CLI (v2.0.22)" + echo " - anchor CLI (v0.31.1)" + echo " - platform tools (v1.48)" + echo " - cargo-build-sbf" + echo "" + echo "Run 'setup-solana' to initialize the development environment" + echo "Create a new Anchor project with: anchor init my-project" + echo "" + ''; + }; + }; + }; + }; +} \ No newline at end of file