### EigenCompute - `ecloud` CLI Quickstart Source: https://context7.com/layr-labs/eigencloud-docs/llms.txt Guide to installing and using the `ecloud` CLI for EigenCompute, including authentication, app deployment, and log streaming. ```APIDOC ## EigenCompute — `ecloud` CLI Quickstart `ecloud` is the primary CLI for EigenCompute. It authenticates with an EVM private key, creates Dockerized app templates for TypeScript/Python/Go/Rust, deploys them into Intel TDX enclaves, and streams logs. Each deployed app receives an auto-provisioned KMS-backed wallet. ### Installation ```bash npm install -g @layr-labs/ecloud-cli ``` ### Authentication Authenticate using an EVM private key. The key can be stored in the OS keyring or generated fresh. ```bash # Login using existing key stored in OS keyring ecloud auth login # OR generate a fresh key and store it ecloud auth generate --store ``` ### Check Authentication Status Verify your authenticated address and environment details. ```bash ecloud auth whoami # Example Output: # Address: 0x9431Cf5DA0CE60664661341db650763B08286B18 ``` ``` -------------------------------- ### Install Dependencies and Run Locally Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigencompute/get-started/quickstart.md Install project dependencies and start a local development server. This is useful for testing your application before deploying. ```bash npm install npm run dev ``` -------------------------------- ### Install CLI and Setup Shell Completion Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Installs the eigenx binary to the user's ~/bin directory and sets up shell completion for convenience. ```bash make install ``` -------------------------------- ### Handle First-Run Setup Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Manages the initial setup for new users, including environment and telemetry configuration. ```go // WithFirstRunSetup handles first-run environment and telemetry setup func WithFirstRunSetup(cCtx *cli.Context) error ``` -------------------------------- ### Write Example .env File Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Writes the example .env file to the project directory. Ensure the configuration is available. ```go err = os.WriteFile(filepath.Join(targetDir, ".env.example"), []byte(config.EnvExample), 0644) if err != nil { return fmt.Errorf("failed to write .env.example: %w", err) } ``` -------------------------------- ### Install DevKit CLI - From Source Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Install the DevKit CLI by cloning the repository and using `make install`. This method automatically configures shell completion. ```bash git clone https://github.com/Layr-Labs/devkit-cli cd devkit-cli make install ``` -------------------------------- ### Global Configuration File Example Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Example of the global DevKit configuration file, showing settings like `first_run` and `telemetry_enabled`. ```yaml first_run: false telemetry_enabled: true ``` -------------------------------- ### Test Call Command Setup Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Provides a setup function for testing the 'call' command, returning a temporary directory, a restore function, the CLI app, and a no-op logger. ```go func setupCallApp(t *testing.T) (tmpDir string, restore func(), app *cli.App, noopLogger *logger.NoopLogger) ``` -------------------------------- ### Project Configuration File Example Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Example of a project-level DevKit configuration file, including `project_uuid` and `telemetry_enabled` settings. ```yaml project_uuid: "12345678-1234-1234-1234-123456789abc" telemetry_enabled: true ``` -------------------------------- ### Install DevKit CLI - Manual Installation (Linux ARM64) Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Manually install the DevKit CLI binary for Linux on ARM64 architecture. Ensure the ~/bin directory exists and add it to your PATH. ```bash mkdir -p $HOME/bin && curl -sL https://s3.amazonaws.com/eigenlayer-devkit-releases/v0.1.0-preview.9.rc/devkit-linux-arm64-v0.1.0-preview.9.rc.tar.gz | tar -x -C "$HOME/bin" -f - ``` -------------------------------- ### Install DevKit CLI - Manual Installation (Linux x86_64) Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Manually install the DevKit CLI binary for Linux on x86_64 architecture. Ensure the ~/bin directory exists and add it to your PATH. ```bash mkdir -p $HOME/bin && curl -sL https://s3.amazonaws.com/eigenlayer-devkit-releases/v0.1.0-preview.9.rc/devkit-linux-amd64-v0.1.0-preview.9.rc.tar.gz | tar -x -C "$HOME/bin" -f - ``` -------------------------------- ### Go Migration Test Setup Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Go code snippet demonstrating the setup for a migration test, including necessary imports and variable declarations for testing migration steps. ```go package migration_test ⋮---- import ( "testing" "github.com/Layr-Labs/devkit-cli/config/contexts" "github.com/Layr-Labs/devkit-cli/pkg/migration" ) ⋮---- "testing" ⋮---- "github.com/Layr-Labs/devkit-cli/config/contexts" "github.com/Layr-Labs/devkit-cli/pkg/migration" ⋮---- func TestMigration_0_1_0_to_0_1_1(t *testing.T) ⋮---- // Test YAML with old block heights ⋮---- // locate the 0.1.0 -> 0.1.1 step from the chain var step migration.MigrationStep ⋮---- // Check that other fields are not modified ``` -------------------------------- ### Start Local Development Server Source: https://github.com/layr-labs/eigencloud-docs/blob/main/README.md Starts a local development server. Changes are reflected live without server restarts. ```bash yarn start ``` -------------------------------- ### EigenDA Node Startup Log Example Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigenda/operator-guides/run-a-node/run-with-docker.mdx This is an example of the expected log output upon successful startup of the EigenDA node. It indicates initialization, service startup, and network readiness. ```log 2024/03/22 19:33:28 maxprocs: Leaving GOMAXPROCS=16: CPU quota undefined 2024/03/22 19:33:30 Initializing Node time=2024-03-22T19:33:34.503Z level=DEBUG source=/app/core/eth/tx.go:791 msg=Addresses blsOperatorStateRetrieverAddr=0xB4baAfee917fb4449f5ec64804217bccE9f46C67 eigenDAServiceManagerAddr=0xD4A7E1Bd8015057293f0D0A557088c286942e84b registryCoordinatorAddr=0x53012C69A189cfA2D9d29eb6F19B32e0A2EA3490 blsPubkeyRegistryAddr=0x066cF95c1bf0927124DFB8B02B401bc23A79730D 2024/03/22 19:33:34 Reading G1 points (4194304 bytes) takes 5.981866ms 2024/03/22 19:33:37 Parsing takes 3.144064399s numthread 8 time=2024-03-22T19:33:38.141Z level=INFO source=/go/pkg/mod/github.com/!layr-!labs/eigensdk-go@v0.1.3-0.20240318050546-8d038f135826/metrics/eigenmetrics.go:81 msg="Starting metrics server at port :9092" time=2024-03-22T19:33:38.141Z level=INFO source=/app/node/node.go:174 msg="Enabled metrics" socket=:9092 time=2024-03-22T19:33:38.141Z level=INFO source=/go/pkg/mod/github.com/!layr-!labs/eigensdk-go@v0.1.3-0.20240318050546-8d038f135826/nodeapi/nodeapi.go:104 msg="Starting node api server at address :9091" time=2024-03-22T19:33:38.141Z level=INFO source=/app/node/node.go:178 msg="Enabled node api" port=9091 time=2024-03-22T19:33:38.141Z level=INFO source=/app/node/node.go:211 msg="The node has successfully started. Note: if it's not opted in on https://app.eigenlayer.xyz/avs/eigenda, then please follow the EigenDA operator guide section in docs.eigenlayer.xyz to register" time=2024-03-22T19:33:38.141Z level=INFO source=/go/pkg/mod/github.com/!layr-!labs/eigensdk-go@v0.1.3-0.20240318050546-8d038f135826/nodeapi/nodeapi.go:238 msg="node api server running" addr=:9091 time=2024-03-22T19:33:38.141Z level=INFO source=/app/node/node.go:385 msg="Start checkRegisteredNodeIpOnChain goroutine in background to subscribe the operator socket change events onchain" time=2024-03-22T19:33:38.142Z level=INFO source=/app/node/node.go:231 msg="Start expireLoop goroutine in background to periodically remove expired batches on the node" time=2024-03-22T19:33:38.142Z level=INFO source=/app/node/node.go:408 msg="Start checkCurrentNodeIp goroutine in background to detect the current public IP of the operator node" time=2024-03-22T19:33:38.142Z level=INFO source=/app/node/grpc/server.go:123 msg=port 32004=address [::]:32004="GRPC Listening" time=2024-03-22T19:33:38.142Z level=INFO source=/app/node/grpc/server.go:99 msg=port 32005=address [::]:32005="GRPC Listening" ``` -------------------------------- ### Display Registry Examples Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Shows example image reference formats for different container registries, tailored to a specific application name. ```go // displayRegistryExamples shows example image reference formats func displayRegistryExamples(appName string) { // ... implementation details ... } ``` -------------------------------- ### General Environment Configuration Example Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md An example of a general environment configuration file. This file is typically used to set up application-wide variables. ```env ``` -------------------------------- ### NoopLogger Usage Example Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Provides a practical example of how to use the NoopLogger in unit tests. Demonstrates creating, using, and asserting log messages. ```go package logger import ( "testing" ) // Example test showing typical usage in unit tests func TestNoopLogger_UsageExample(t *testing.T) ``` -------------------------------- ### Test Info Command Setup (Go) Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Sets up a test environment for the 'info' command, including creating temporary directories and configuration files. ```go package template ⋮---- import ( "flag" "os" "path/filepath" "testing" "github.com/Layr-Labs/devkit-cli/pkg/common" "github.com/Layr-Labs/devkit-cli/pkg/testutils" "github.com/urfave/cli/v2" ) ⋮---- "flag" "os" "path/filepath" "testing" ⋮---- "github.com/Layr-Labs/devkit-cli/pkg/common" "github.com/Layr-Labs/devkit-cli/pkg/testutils" "github.com/urfave/cli/v2" ⋮---- func TestInfoCommand(t *testing.T) ⋮---- // Create a temporary directory for testing ⋮---- // Create config directory and config.yaml ⋮---- // Create config with template information ⋮---- // Create test context with no-op logger ⋮---- // Change to the test directory ⋮---- //nolint:errcheck ⋮---- // Test info command ⋮---- // Create a flag set and context with no-op logger ⋮---- // Execute the Before hook to set up the logger context ⋮---- // Run the info command ``` -------------------------------- ### Setup TLS for EigenX Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md This shell script configures TLS by obtaining a certificate using tls-keygen and starting the Caddy reverse proxy. It requires DOMAIN and MNEMONIC environment variables to be set. TLS setup is conditional on the presence of the tls-keygen binary. ```shell setup_tls() { # If tls-keygen isn't present, TLS wasn't configured during build if [ ! -x /usr/local/bin/tls-keygen ]; then echo "compute-source-env.sh: TLS not configured (no tls-keygen binary)" return 0 fi local domain="${DOMAIN:-}" local mnemonic="${MNEMONIC:-}" # Since tls-keygen is present, TLS is expected - validate requirements if [ -z "$domain" ] || [ "$domain" = "localhost" ]; then echo "compute-source-env.sh: ERROR - TLS binary present but DOMAIN not configured or is localhost" echo "compute-source-env.sh: Set DOMAIN environment variable to a valid domain" exit 1 fi if [ -z "$mnemonic" ]; then echo "compute-source-env.sh: ERROR - TLS binary present but MNEMONIC not available" echo "compute-source-env.sh: Cannot obtain TLS certificate without mnemonic" exit 1 fi if [ ! -x /usr/local/bin/caddy ]; then echo "compute-source-env.sh: ERROR - TLS binary present but Caddy not found" exit 1 fi echo "compute-source-env.sh: Setting up TLS for domain: $domain" # Obtain TLS certificate using ACME # Default to http-01, but allow override via ACME_CHALLENGE env var local challenge="${ACME_CHALLENGE:-http-01}" # Check if we should use staging (for testing) local staging_flag="" if [ "${ACME_STAGING:-false}" = "true" ]; then staging_flag="-staging" echo "compute-source-env.sh: Using Let's Encrypt STAGING environment (certificates won't be trusted)" fi echo "compute-source-env.sh: Obtaining TLS certificate using $challenge challenge..." # Pass the API URL for certificate persistence if ! MNEMONIC="$mnemonic" DOMAIN="$domain" API_URL=\"{{.UserAPIURL}}\" /usr/local/bin/tls-keygen \ -challenge "$challenge" \ $staging_flag; then echo "compute-source-env.sh: ERROR - Failed to obtain TLS certificate" echo "compute-source-env.sh: Certificate issuance failed for $domain" exit 1 fi echo "compute-source-env.sh: TLS certificate obtained successfully" # Validate Caddyfile before starting if ! /usr/local/bin/caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile 2>/dev/null; then echo "compute-source-env.sh: ERROR - Invalid Caddyfile" echo "compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed" exit 1 fi # Start Caddy in background echo "compute-source-env.sh: Starting Caddy reverse proxy..." # Check if Caddy logs should be enabled if [ "${ENABLE_CADDY_LOGS:-false}" = "true" ]; then if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile 2>&1; then echo "compute-source-env.sh: ERROR - Failed to start Caddy" echo "compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed" exit 1 fi else # Redirect Caddy output to /dev/null to silence logs if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1; then echo "compute-source-env.sh: ERROR - Failed to start Caddy" echo "compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed" exit 1 fi fi # Give Caddy a moment to fully initialize sleep 2 echo "compute-source-env.sh: Caddy started successfully" return 0 } # Run TLS setup setup_tls echo "compute-source-env.sh: Environment sourced." exec "$@" ``` -------------------------------- ### Get AVS Setup Configuration Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Gathers AVS-related configuration details, including private keys and metadata URLs, from the command context flags. ```go func getAVSSetup(cCtx *cli.Context) (*common.AvsConfig, error) ``` -------------------------------- ### Install EigenX CLI on Windows Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md This script installs the EigenX CLI on Windows. It supports installing either the stable or development version and prompts the user for the installation directory. Administrator privileges may be required for system-wide installations. ```powershell # EigenX CLI Installation Script for Windows param( [switch]$Dev, [switch]$Interactive ) # Error handling $ErrorActionPreference = "Stop" # Initialize cleanup variable $tempFile = $null # Check for --dev flag (support both -Dev switch and --dev argument) if ($Dev -or ($args.Count -gt 0 -and $args[0] -eq "--dev")) { Write-Host "Installing dev version of EigenX..." # Dev version - read from dev S3 bucket $EIGENX_VERSION = (Invoke-WebRequest -Uri "https://s3.amazonaws.com/eigenlayer-eigenx-releases-dev/VERSION" -UseBasicParsing).Content.Trim() $EIGENX_BASE_URL = "https://s3.amazonaws.com/eigenlayer-eigenx-releases-dev" } else { Write-Host "Installing stable version of EigenX..." # Stable version - read from prod S3 bucket $EIGENX_VERSION = (Invoke-WebRequest -Uri "https://s3.amazonaws.com/eigenlayer-eigenx-releases/VERSION" -UseBasicParsing).Content.Trim() $EIGENX_BASE_URL = "https://s3.amazonaws.com/eigenlayer-eigenx-releases" } # Detect platform $OS = "windows" $ARCH = $env:PROCESSOR_ARCHITECTURE switch ($ARCH) { "AMD64" { $ARCH = "amd64" } "ARM64" { $ARCH = "arm64" } "x86" { Write-Host "Error: 32-bit Windows is not supported" exit 1 } default { Write-Host "Error: Unsupported architecture: $ARCH" exit 1 } } $PLATFORM = "${OS}-${ARCH}" # Function to test if running as administrator function Test-Administrator { $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } # Prompt for installation directory # Check if we're in a truly interactive session or explicitly requested $isInteractive = $Interactive -or ([Environment]::UserInteractive -and -not [Console]::IsInputRedirected) if ($isInteractive) { # Interactive session available Write-Host "Where would you like to install EigenX?" Write-Host "1) $env:USERPROFILE\bin (recommended)" Write-Host "2) C:\Program Files\EigenX (system-wide, requires admin)" Write-Host "3) Custom path" do { $choice = Read-Host "Enter choice (1-3) [1]" if ([string]::IsNullOrWhiteSpace($choice)) { $choice = "1" } } while ($choice -notin @("1", "2", "3")) } else { # Non-interactive (piped), use default Write-Host "Installing to $env:USERPROFILE\bin (default for non-interactive install)" $choice = "1" } switch ($choice) { "1" { $INSTALL_DIR = "$env:USERPROFILE\bin" $needsAdmin = $false } "2" { $INSTALL_DIR = "C:\Program Files\EigenX" $needsAdmin = $true } "3" { do { $INSTALL_DIR = Read-Host "Enter custom path" } while ([string]::IsNullOrWhiteSpace($INSTALL_DIR)) # Check if custom path requires admin (system directories) $needsAdmin = $INSTALL_DIR.StartsWith("C:\Program Files") -or $INSTALL_DIR.StartsWith("C:\Windows") -or $INSTALL_DIR.StartsWith("C:\ProgramData") } } # Check admin privileges if needed if ($needsAdmin -and -not (Test-Administrator)) { Write-Host "Error: Installation to '$INSTALL_DIR' requires administrator privileges." Write-Host "Please run this script as Administrator or choose a different installation directory." exit 1 } # Create directory if it doesn't exist if (-not (Test-Path $INSTALL_DIR)) { try { New-Item -ItemType Directory -Path $INSTALL_DIR -Force | Out-Null } catch { Write-Host "Error: Failed to create directory '$INSTALL_DIR': $($_.Exception.Message)" exit 1 } } # Download and install $EIGENX_URL = "${EIGENX_BASE_URL}/${EIGENX_VERSION}/eigenx-cli-${PLATFORM}-${EIGENX_VERSION}.zip" Write-Host "Downloading EigenX ${EIGENX_VERSION} for ${PLATFORM}..." try { # Create temporary file for download $tempFile = [System.IO.Path]::GetTempFileName() + ".zip" # Download the binary file Invoke-WebRequest -Uri $EIGENX_URL -OutFile $tempFile -UseBasicParsing # Extract to installation directory Write-Host "Extracting to $INSTALL_DIR..." Expand-Archive -Path $tempFile -DestinationPath $INSTALL_DIR -Force Write-Host "✅ EigenX installed to $INSTALL_DIR\eigenx.exe" } catch { Write-Host "Error: Failed to download or install EigenX: $($_.Exception.Message)" exit 1 } finally { # Clean up temp file if ($tempFile -and (Test-Path $tempFile)) { Remove-Item $tempFile -Force -ErrorAction SilentlyContinue } } ``` -------------------------------- ### Test Upgrade Command Setup Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Sets up the testing environment for the upgrade command, including creating temporary directories, mock configurations, and mock Git clients. ```go func TestUpgradeCommand(t *testing.T) ⋮---- // Create a temporary directory for testing ⋮---- // Ensure test directory is clean ⋮---- // Create config directory and config.yaml ⋮---- // Create config with template information - using inline yaml ⋮---- // Create git repo in temp dir ⋮---- // Create mock template info getter ⋮---- // Create the test command with mocked dependencies ⋮---- // Create test context ⋮---- // Change to the test directory ⋮---- //nolint:errcheck ⋮---- ``` -------------------------------- ### Verify DevKit Installation Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigenlayer/developers/howto/get-started-with-devkit/start-building-task-based-avs.md Run this command after installation to confirm that the DevKit CLI is installed correctly and accessible. ```bash devkit --help ``` -------------------------------- ### CLI Context Command Setup and Tests Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Provides setup functions and unit tests for CLI commands related to context management, including flag registration, command execution, and YAML file manipulation. It covers creating, listing, and setting contexts. ```go package context ⋮---- import ( "flag" "fmt" "io" "math/big" "os" "path/filepath" "sort" "strings" "testing" "github.com/Layr-Labs/devkit-cli/pkg/common" "github.com/Layr-Labs/devkit-cli/pkg/common/iface" "github.com/Layr-Labs/devkit-cli/pkg/common/logger" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" "gopkg.in/yaml.v3" ) ⋮---- "flag" "fmt" "io" "math/big" "os" "path/filepath" "sort" "strings" "testing" ⋮---- "github.com/Layr-Labs/devkit-cli/pkg/common" "github.com/Layr-Labs/devkit-cli/pkg/common/iface" "github.com/Layr-Labs/devkit-cli/pkg/common/logger" "github.com/stretchr/testify/require" "github.com/urfave/cli/v2" "gopkg.in/yaml.v3" ⋮---- func setupCLIContext(cmd *cli.Command, args []string, flags map[string]string) *cli.Context ⋮---- // silence usage output during tests ⋮---- // Register command flags (and any globals you included in cmd.Flags) ⋮---- // Stable ordering and --key=value to avoid value miss-association ⋮---- // Create app with no-op logger and progress tracker ⋮---- // Execute the Before hook to set up the logger context ⋮---- func TestNewModelDefaults(t *testing.T) ⋮---- func TestCreateContextFunction(t *testing.T) ⋮---- // Persist and optionally make current ⋮---- func TestCreateContextCommand_CreatesFile(t *testing.T) ⋮---- // stub chain id resolver to avoid dialing RPC ⋮---- // return a consistent ID regardless of URL ⋮---- // chdir into temp workspace ⋮---- // build CLI context: // - pass all flags to avoid prompts // - --use=false so we do not try to update config/config.yaml ⋮---- // run ⋮---- // assert file ⋮---- func TestListContexts_NoDir(t *testing.T) ⋮---- func TestListContexts_EmptyDir(t *testing.T) ⋮---- func TestListContexts_Success(t *testing.T) ⋮---- func TestSetFlagWritesYAML(t *testing.T) ⋮---- // prepare temp config/contexts/test.yaml ⋮---- // set up CLI with --context test and --set project.name=new ⋮---- // execute ⋮---- // verify YAML updated ⋮---- var doc yaml.Node ⋮---- // navigate to context.project.name ⋮---- var found string ⋮---- func TestContextSetsGlobalContext(t *testing.T) ⋮---- // prepare temp config/config.yaml and a dummy context file ⋮---- // config.yaml ⋮---- // contexts/prod.yaml (must exist so Action doesn't error) ⋮---- // set up CLI with --context prod (no --list) ⋮---- // verify config.yaml has project.context=prod ⋮---- func TestSettingNonexistentContextFails(t *testing.T) ⋮---- // Prepare a temp project with a valid config.yaml but no contexts/foo.yaml ⋮---- // Create config/config.yaml ⋮---- // Create an empty contexts directory ⋮---- // Build CLI context for Command with --context=foo (which does not exist) ⋮---- // Switch into tmp so relative paths resolve ⋮---- // Execute ⋮---- // Check the error message suggests creating the context ``` -------------------------------- ### Setup Telemetry Client Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Initializes and returns a telemetry client based on the provided cli.Context. ```go func setupTelemetry(cCtx *cli.Context) telemetry.Client ``` -------------------------------- ### Verify ecloud CLI Installation Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigencompute/howto/setup/migrate-ecloud-cli.md Check if the ecloud CLI has been installed successfully by running the version command. This verifies the installation before proceeding with migration. ```bash ecloud version ``` -------------------------------- ### Test Command Setup and Execution Logic Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Contains test utility functions and the core logic for the 'test' command, including setup for test applications, handling missing configuration files, and executing test scripts. ```go package commands ⋮---- import ( "context" "errors" "os" "path/filepath" "testing" "time" "github.com/Layr-Labs/devkit-cli/pkg/common/logger" "github.com/Layr-Labs/devkit-cli/pkg/testutils" "github.com/stretchr/testify/assert" "github.com/urfave/cli/v2" ) ⋮---- "context" "errors" "os" "path/filepath" "testing" "time" ⋮---- "github.com/Layr-Labs/devkit-cli/pkg/common/logger" "github.com/Layr-Labs/devkit-cli/pkg/testutils" ⋮---- "github.com/stretchr/testify/assert" "github.com/urfave/cli/v2" ⋮---- func setupTestApp(t *testing.T) (tmpDir string, restoreWD func(), app *cli.App, noopLogger *logger.NoopLogger) ⋮---- // Create the test script ⋮---- func TestTestCommand_ExecutesSuccessfully(t *testing.T) ⋮---- // Check that the expected message was logged ⋮---- func TestTestCommand_MissingDevnetYAML(t *testing.T) ⋮---- func TestTestCommand_MissingScript(t *testing.T) ⋮---- func TestTestCommand_ScriptReturnsNonZero(t *testing.T) ⋮---- func TestTestCommand_Cancelled(t *testing.T) ``` -------------------------------- ### Setup Layered Build Directory Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Prepares a directory for a layered Docker build, including writing the layered Dockerfile, a wrapper script, and copying necessary binaries (KMS, TLS). ```go // Write layered Dockerfile // Write wrapper script // Copy KMS keys // Copy kms-client binary // Only include TLS components if requested // Copy tls-keygen binary // Handle Caddyfile - check if user has one in current directory // User has a Caddyfile, use it // No user Caddyfile but TLS is requested // Unexpected error reading Caddyfile func setupLayeredBuildDirectory(environmentConfig common.EnvironmentConfig, layeredDockerfileContent []byte, scriptContent []byte, includeTLS bool) (string, error) ``` -------------------------------- ### Install EigenLayer DevKit CLI Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigenlayer/developers/howto/get-started-with-devkit/start-building-task-based-avs.md Use this command to download and install the EigenLayer DevKit CLI. Refer to the DevKit repository for alternative installation methods. ```bash curl -fsSL https://raw.githubusercontent.com/Layr-Labs/devkit-cli/main/install-devkit.sh | bash ``` -------------------------------- ### Install Eigencloud DevKit Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md This bash script automates the download and installation of the Eigencloud DevKit. It detects the operating system and architecture, prompts the user for an installation directory (defaulting to $HOME/bin), and adds the DevKit to the PATH if necessary. Ensure you have `curl` and `tar` installed. ```bash #!/bin/bash set -e # DevKit version DEVKIT_VERSION=$(curl -fsSL https://raw.githubusercontent.com/Layr-Labs/devkit-cli/main/VERSION) DEVKIT_BASE_URL="https://s3.amazonaws.com/eigenlayer-devkit-releases" # Detect platform OS=$(uname -s | tr '[:upper:]' '[:lower:]') ARCH=$(uname -m) case $OS in darwin) OS="darwin" ;; linux) OS="linux" ;; *) echo "Error: Unsupported OS: $OS"; exit 1 ;; esac case $ARCH in x86_64|amd64) ARCH="amd64" ;; arm64|aarch64) ARCH="arm64" ;; *) echo "Error: Unsupported architecture: $ARCH"; exit 1 ;; esac PLATFORM="${OS}-${ARCH}" # Prompt for installation directory if [[ -t 0 ]]; then # Interactive terminal available echo "Where would you like to install DevKit?" echo "1) $HOME/bin (recommended)" echo "2) /usr/local/bin (system-wide, requires sudo)" echo "3) Custom path" read -p "Enter choice (1-3) [1]: " choice else # Non-interactive (piped), use default echo "Installing to $HOME/bin (default for non-interactive install)" choice=1 fi case ${choice:-1} in 1) INSTALL_DIR="$HOME/bin" ;; 2) INSTALL_DIR="/usr/local/bin" ;; 3) read -p "Enter custom path: " INSTALL_DIR if [[ -z "$INSTALL_DIR" ]]; then echo "Error: No path provided" exit 1 fi ;; *) echo "Invalid choice"; exit 1 ;; esac # Create directory if it doesn't exist if [[ "$INSTALL_DIR" == "/usr/local/bin" ]]; then sudo mkdir -p "$INSTALL_DIR" else mkdir -p "$INSTALL_DIR" fi # Download and install DEVKIT_URL="${DEVKIT_BASE_URL}/${DEVKIT_VERSION}/devkit-${PLATFORM}-${DEVKIT_VERSION}.tar.gz" echo "Downloading DevKit ${DEVKIT_VERSION} for ${PLATFORM}..." if [[ "$INSTALL_DIR" == "/usr/local/bin" ]]; then curl -sL "$DEVKIT_URL" | sudo tar -x -C "$INSTALL_DIR" -f - else curl -sL "$DEVKIT_URL" | tar -x -C "$INSTALL_DIR" -f - fi echo "✅ DevKit installed to $INSTALL_DIR/devkit" # Add to PATH if needed if [[ "$INSTALL_DIR" == "$HOME/bin" ]] && [[ ":$PATH:" != ":$HOME/bin:"* ]]; then echo "💡 Add $HOME/bin to your PATH:" echo " echo 'export PATH=\" $HOME/bin:$PATH\" ' >> ~/.$(basename $SHELL)rc" fi echo "🚀 Verify installation: $INSTALL_DIR/devkit --help" ``` -------------------------------- ### Install Docker Buildx on macOS Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Installs Docker Buildx using Homebrew and links it to the Docker CLI plugins directory. Ensures the CLI-plugins directory exists and then symlinks the Homebrew-installed buildx binary. Finally, it installs buildx as the default builder and verifies the installation. ```bash brew install docker-buildx # ensure the CLI-plugins dir exists mkdir -p ~/.docker/cli-plugins # symlink the Homebrew buildx into Dockers plugin folder ln -sf "$(brew --prefix)/bin/docker-buildx" ~/.docker/cli-plugins/docker-buildx # install it as the default builder docker buildx install # verify docker buildx version ``` -------------------------------- ### Navigate to Project Directory Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigencompute/howto/build/attestedAPI-template.md After creating the application, change into the newly created project directory to proceed with building and deployment. ```bash cd myproject ``` -------------------------------- ### Install EigenLayer CLI using Go Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigenlayer/operators/howto/registeroperators/operator-installation.md Install the EigenLayer CLI directly using the Go programming language. This command installs the executable, library, and dependencies. ```go go install github.com/Layr-Labs/eigenlayer-cli/cmd/eigenlayer@latest ``` -------------------------------- ### Install EigenLayer CLI using Binary Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigenlayer/operators/howto/registeroperators/operator-installation.md Download and install the latest release of the EigenLayer CLI using a script. The binary is typically installed in the `~/bin` directory. ```bash curl -sSfL https://raw.githubusercontent.com/layr-labs/eigenlayer-cli/master/scripts/install.sh | sh -s ``` ```bash export PATH=$PATH:~/bin ``` -------------------------------- ### Handle Telemetry Setup Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Configures telemetry settings, including prompts and global preferences, during the first run. ```go // handleTelemetrySetup handles the telemetry setup part of first-run setup func handleTelemetrySetup(cCtx *cli.Context, logger iface.Logger) error ``` -------------------------------- ### Start Stopped Application Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Start an application that is currently stopped. ```bash eigenx app start [app-id|name] ``` -------------------------------- ### Implement Login Action Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Handles the execution of the 'login' command. It determines the key name, checks for existing keys, prompts for confirmation to overwrite, securely prompts for the private key, derives the address, and stores the key in the keyring. ```go package auth import ( "fmt" "github.com/Layr-Labs/eigenx-cli/pkg/common" "github.com/Layr-Labs/eigenx-cli/pkg/common/output" "github.com/urfave/cli/v2" ) func loginAction(cCtx *cli.Context) // Determine the key name // Check if key already exists // Key exists, ask for confirmation to overwrite with strong warning // Prompt for private key with hidden input // Get address from private key for display // Store in keyring ``` -------------------------------- ### Install EigenX CLI Development Version Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Install the development version of the EigenX CLI using a curl script with the --dev flag. This installs the CLI as `eigenx-dev`. ```bash curl -fsSL https://eigenx-scripts.s3.us-east-1.amazonaws.com/install-eigenx.sh | bash -s -- --dev ``` -------------------------------- ### List Available Deployment Environments (Go) Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Use this command to display all available deployment environments. It marks the currently active environment and provides descriptions for each. ```go package environment import ( "fmt" "github.com/Layr-Labs/eigenx-cli/pkg/commands/utils" "github.com/Layr-Labs/eigenx-cli/pkg/common" "github.com/urfave/cli/v2" ) var ListCommand = &cli.Command{ Name: "list", Usage: "List available deployment environments", Action: func(cCtx *cli.Context) error { logger := common.LoggerFromContext(cCtx) // Get active deployment environment to mark it currentEnvConfig, err := utils.GetEnvironmentConfig(cCtx) if err != nil { return fmt.Errorf("failed to get active deployment environment: %w", err) } logger.Info("Available deployment environments:") // List all available deployment environments from EnvironmentConfigs for name, config := range common.EnvironmentConfigs { marker := "" if name == currentEnvConfig.Name { marker = " (active)" } // Add description based on environment description := utils.GetEnvironmentDescription(name, config.Name, true) logger.Info(" • %s %s%s", name, description, marker) } return nil }, } ``` -------------------------------- ### Install Eigenx Binary based on OS and Architecture Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Installs the Eigenx binary by downloading the appropriate tar.gz or zip file based on the matrix configuration (OS and architecture). Sets the binary path in the environment. ```bash - name: Install eigenx binary run: | set -euxo pipefail ver="${{ env.VERSION }}" case "${{ matrix.os }}-${{ matrix.arch }}" in "macos-latest-x64") url="https://s3.amazonaws.com/eigenlayer-eigenx-releases/${ver}/eigenx-cli-darwin-amd64-${ver}.tar.gz" ;; "macos-latest-arm64") url="https://s3.amazonaws.com/eigenlayer-eigenx-releases/${ver}/eigenx-cli-darwin-arm64-${ver}.tar.gz" ;; "ubuntu-latest-x64") url="https://s3.amazonaws.com/eigenlayer-eigenx-releases/${ver}/eigenx-cli-linux-amd64-${ver}.tar.gz" ;; "ubuntu-latest-arm64")url="https://s3.amazonaws.com/eigenlayer-eigenx-releases/${ver}/eigenx-cli-linux-arm64-${ver}.tar.gz" ;; *) echo "Unsupported combination"; exit 1 ;; esac mkdir -p "$HOME/bin" curl -fsSL "$url" | tar xzv -C "$HOME/bin" echo "$HOME/bin" >> $GITHUB_PATH ``` -------------------------------- ### installFromRemote Method for LegoManager Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Installs a certificate from remote storage locally. It verifies the certificate against the provided private key and writes the files. ```go // installFromRemote installs a certificate from remote storage func (m *LegoManager) installFromRemote(outDir string, chain storage.ChainPEM, tlsKey *ecdsa.PrivateKey, expiry time.Time) (storage.Bundle, error) { // Verify the certificate matches our key // (Implementation omitted for brevity, but would involve parsing chain and key) // Write certificate and key files _, _, err := m.writeCertificateFiles(outDir, chain, tlsKey) if err != nil { return storage.Bundle{}, fmt.Errorf("failed to write certificate files: %w", err) } return storage.Bundle{ Chain: chain, PrivateKey: nil, // Private key is not stored in the bundle when installing from remote CertExpiry: expiry, }, nil } ``` -------------------------------- ### Install DevKit CLI - Manual Installation (macOS Intel) Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Manually install the DevKit CLI binary for macOS on Intel architecture. Ensure the ~/bin directory exists and add it to your PATH. ```bash mkdir -p $HOME/bin && curl -sL https://s3.amazonaws.com/eigenlayer-devkit-releases/v0.1.0-preview.9.rc/devkit-darwin-amd64-v0.1.0-preview.9.rc.tar.gz | tar -x -C "$HOME/bin" -f - ``` -------------------------------- ### Install Dependencies Source: https://github.com/layr-labs/eigencloud-docs/blob/main/README.md Run this command to install project dependencies using Yarn. ```bash yarn ``` -------------------------------- ### Initial EigenX CLI Setup Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/eigenx.md Log in to your Docker registry and authenticate with EigenX CLI using a private key. If you don't have a private key, generate one using `eigenx auth generate --store`. ```bash # Log in to your Docker registry (required to push images) docker login # Log in with an existing private key eigenx auth login ``` -------------------------------- ### Install DevKit CLI - Manual Installation (macOS Apple Silicon) Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Manually install the DevKit CLI binary for macOS on Apple Silicon architecture. Ensure the ~/bin directory exists and add it to your PATH. ```bash mkdir -p $HOME/bin && curl -sL https://s3.amazonaws.com/eigenlayer-devkit-releases/v0.1.0-preview.9.rc/devkit-darwin-arm64-v0.1.0-preview.9.rc.tar.gz | tar -x -C "$HOME/bin" -f - ``` -------------------------------- ### Initialize Project with Template Script Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Executes a template script to initialize a new project. It expects a non-JSON response from the script. ```go if _, err = common.CallTemplateScript(cCtx.Context, logger, targetDir, scriptPath, common.ExpectNonJSONResponse, []byte(mainLang)); err != nil { return fmt.Errorf("failed to initialize %s: %w", scriptPath, err) } ``` -------------------------------- ### eigenx app start Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigencompute/reference/eigenx-cli/app.md Starts a previously stopped application. You can specify the application by its ID or name. ```APIDOC ## eigenx app start ### Description Start a previously stopped application. ### Synopsis `eigenx app start [global options] []` ### Arguments `app-id|name` (string) > Application ID or display name. Prompted for if not provided. ``` -------------------------------- ### Install Eigencloud Devkit in GitHub Actions Source: https://github.com/layr-labs/eigencloud-docs/blob/main/static/devkit.md Installs the Eigencloud Devkit by downloading a versioned tarball based on the matrix OS and architecture. It sets up the devkit in the user's bin directory and verifies the installation against an expected version. ```bash - name: Install devkit run: | set -euxo pipefail ver="${{ env.VERSION }}" case "${{ matrix.os }}-${{ matrix.arch }}" in "macos-latest-x64") url="https://s3.amazonaws.com/eigenlayer-devkit-releases/${ver}/devkit-darwin-amd64-${ver}.tar.gz" ;; "macos-latest-arm64") url="https://s3.amazonaws.com/eigenlayer-devkit-releases/${ver}/devkit-darwin-arm64-${ver}.tar.gz" ;; "ubuntu-latest-x64") url="https://s3.amazonaws.com/eigenlayer-devkit-releases/${ver}/devkit-linux-amd64-${ver}.tar.gz" ;; "ubuntu-latest-arm64")url="https://s3.amazonaws.com/eigenlayer-devkit-releases/${ver}/devkit-linux-arm64-${ver}.tar.gz" ;; *) echo "Unsupported combination"; exit 1 ;; esac mkdir -p "$HOME/bin" echo "::set-output name=url::$url" curl -fsSL "$url" | tar -x -C "$HOME/bin" -f - ``` ```bash - name: Verify installation run: | export PATH="$HOME/bin:$PATH" # expected version from file ver="${{ env.VERSION }}" # extract the `devkit version` Version line installed=$(devkit version \ | awk '/^Version:/ { print $2 }') if [[ "$installed" != "$ver" ]]; then echo "✖ version mismatch: expected $ver, got $installed" exit 1 fi echo "✔ version $installed matches expected $ver" ``` -------------------------------- ### Navigate to Monitoring Directory and Copy Environment File Source: https://github.com/layr-labs/eigencloud-docs/blob/main/docs/eigenda/operator-guides/metrics-and-monitoring.md Change directory to the monitoring folder and create a local .env file from the example. Ensure the prometheus.yml path is correct in the .env file. ```bash cd monitoring cp .env.example .env ```