@layr-labs/ecloud-sdk 0.1.1 → 0.1.2-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +2 -2
- package/dist/billing.cjs +1 -1
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +1 -1
- package/dist/billing.d.ts +1 -1
- package/dist/billing.js +2 -2
- package/dist/{chunk-73YDSHDG.js → chunk-JLZOAV5R.js} +3 -3
- package/dist/chunk-JLZOAV5R.js.map +1 -0
- package/dist/{chunk-XNWF467Z.js → chunk-JRFZVVUB.js} +2 -2
- package/dist/chunk-JRFZVVUB.js.map +1 -0
- package/dist/{chunk-LUFEUEOG.js → chunk-XDS4EF4J.js} +225 -52
- package/dist/chunk-XDS4EF4J.js.map +1 -0
- package/dist/{compute-gpepEsn3.d.ts → compute-BlUpqWKo.d.cts} +93 -15
- package/dist/{compute-B_ibIORD.d.cts → compute-CottWiST.d.ts} +93 -15
- package/dist/compute.cjs +479 -31
- package/dist/compute.cjs.map +1 -1
- package/dist/compute.d.cts +2 -2
- package/dist/compute.d.ts +2 -2
- package/dist/compute.js +2 -2
- package/dist/{index-D-SUX3IG.d.ts → index-Fb_S-Cqk.d.cts} +98 -6
- package/dist/{index-D-SUX3IG.d.cts → index-Fb_S-Cqk.d.ts} +98 -6
- package/dist/index.cjs +223 -56
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +45 -158
- package/dist/index.d.ts +45 -158
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
- package/dist/chunk-73YDSHDG.js.map +0 -1
- package/dist/chunk-LUFEUEOG.js.map +0 -1
- package/dist/chunk-XNWF467Z.js.map +0 -1
package/dist/compute.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/compute.ts","../src/client/modules/compute/app/index.ts","../src/client/common/config/environment.ts","../src/client/common/docker/build.ts","../src/client/common/constants.ts","../src/client/common/docker/layer.ts","../src/client/common/docker/inspect.ts","../src/client/common/docker/push.ts","../src/client/common/templates/dockerfileTemplate.ts","../src/client/common/templates/Dockerfile.layered.tmpl","../src/client/common/templates/scriptTemplate.ts","../src/client/common/templates/compute-source-env.sh.tmpl","../keys/mainnet-alpha/prod/kms-encryption-public-key.pem","../keys/mainnet-alpha/prod/kms-signing-public-key.pem","../keys/sepolia/dev/kms-encryption-public-key.pem","../keys/sepolia/dev/kms-signing-public-key.pem","../keys/sepolia/prod/kms-encryption-public-key.pem","../keys/sepolia/prod/kms-signing-public-key.pem","../src/client/common/utils/keys.ts","../src/client/common/utils/dirname.ts","../src/client/common/registry/digest.ts","../src/client/common/encryption/kms.ts","../src/client/common/env/parser.ts","../src/client/common/release/prepare.ts","../src/client/common/contract/caller.ts","../src/client/common/contract/eip7702.ts","../src/client/common/abis/ERC7702Delegator.json","../src/client/common/utils/logger.ts","../src/client/common/utils/userapi.ts","../src/client/common/utils/auth.ts","../src/client/common/utils/helpers.ts","../src/client/common/abis/AppController.json","../src/client/common/abis/PermissionController.json","../src/client/common/contract/watcher.ts","../src/client/common/utils/validation.ts","../src/client/common/utils/preflight.ts","../src/client/common/telemetry/noop.ts","../src/client/common/telemetry/posthog.ts","../src/client/common/telemetry/index.ts","../src/client/common/telemetry/metricsContext.ts","../src/client/common/telemetry/wrapper.ts","../src/client/modules/compute/app/deploy.ts","../src/client/common/utils/permissions.ts","../src/client/modules/compute/app/upgrade.ts","../src/client/modules/compute/app/create.ts","../src/client/common/templates/catalog.ts","../src/client/common/templates/git.ts","../src/client/common/templates/postprocess.ts","../src/client/modules/compute/app/logs.ts","../src/client/modules/compute/index.ts"],"sourcesContent":["/**\n * Compute module entry point\n *\n * Import from \"@layr-labs/ecloud-sdk/compute\" for direct access to compute/app modules\n */\n\nexport * from \"./client/modules/compute\";\n","/**\n * Main App namespace entry point\n */\n\nimport { parseAbi, encodeFunctionData } from \"viem\";\nimport { deploy as deployApp } from \"./deploy\";\nimport { upgrade as upgradeApp } from \"./upgrade\";\nimport { createApp, CreateAppOpts } from \"./create\";\nimport { logs, LogsOptions } from \"./logs\";\n\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport {\n sendAndWaitForTransaction,\n undelegate,\n isDelegated,\n} from \"../../../common/contract/caller\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\nimport type { AppId, DeployAppOpts, LifecycleOpts, UpgradeAppOpts } from \"../../../common/types\";\nimport { getLogger, addHexPrefix } from \"../../../common/utils\";\n\n// Minimal ABI\nconst CONTROLLER_ABI = parseAbi([\n \"function startApp(address appId)\",\n \"function stopApp(address appId)\",\n \"function terminateApp(address appId)\",\n]);\n\n/**\n * Encode start app call data for gas estimation\n */\nexport function encodeStartAppData(appId: AppId): `0x${string}` {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"startApp\",\n args: [appId],\n });\n}\n\n/**\n * Encode stop app call data for gas estimation\n */\nexport function encodeStopAppData(appId: AppId): `0x${string}` {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"stopApp\",\n args: [appId],\n });\n}\n\n/**\n * Encode terminate app call data for gas estimation\n */\nexport function encodeTerminateAppData(appId: AppId): `0x${string}` {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"terminateApp\",\n args: [appId],\n });\n}\n\nexport interface AppModule {\n create: (opts: CreateAppOpts) => Promise<void>;\n deploy: (opts: DeployAppOpts) => Promise<{\n appId: AppId;\n tx: `0x${string}`;\n appName: string;\n imageRef: string;\n ipAddress?: string;\n }>;\n upgrade: (\n appId: AppId,\n opts: UpgradeAppOpts,\n ) => Promise<{ tx: `0x${string}`; appId: string; imageRef: string }>;\n logs: (opts: LogsOptions) => Promise<void>;\n start: (appId: AppId, opts?: LifecycleOpts) => Promise<{ tx: `0x${string}` | false }>;\n stop: (appId: AppId, opts?: LifecycleOpts) => Promise<{ tx: `0x${string}` | false }>;\n terminate: (appId: AppId, opts?: LifecycleOpts) => Promise<{ tx: `0x${string}` | false }>;\n isDelegated: () => Promise<boolean>;\n undelegate: () => Promise<{ tx: `0x${string}` | false }>;\n}\n\nexport interface AppModuleConfig {\n verbose?: boolean;\n privateKey: `0x${string}`;\n rpcUrl: string;\n environment: string;\n clientId?: string;\n skipTelemetry?: boolean; // Skip telemetry when called from CLI\n}\n\nexport function createAppModule(ctx: AppModuleConfig): AppModule {\n const privateKey = addHexPrefix(ctx.privateKey);\n const skipTelemetry = ctx.skipTelemetry || false;\n\n // Pull config for selected Environment\n const environment = getEnvironmentConfig(ctx.environment);\n\n // Get logger that respects verbose setting\n const logger = getLogger(ctx.verbose);\n\n return {\n async create(opts) {\n return createApp(opts, logger);\n },\n // Write operations\n async deploy(opts) {\n // Map DeployAppOpts to SDKDeployOptions and call the deploy function\n const result = await deployApp(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environment: ctx.environment,\n appName: opts.name,\n instanceType: opts.instanceType,\n dockerfilePath: opts.dockerfile,\n envFilePath: opts.envFile,\n imageRef: opts.imageRef,\n logVisibility: opts.logVisibility,\n gas: opts.gas,\n },\n logger,\n );\n\n return {\n appId: result.appId as AppId,\n tx: result.txHash,\n ipAddress: result.ipAddress,\n appName: result.appName,\n imageRef: result.imageRef,\n };\n },\n\n async upgrade(appId, opts) {\n // Map UpgradeAppOpts to SDKUpgradeOptions and call the upgrade function\n const result = await upgradeApp(\n {\n appId: appId,\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environment: ctx.environment,\n instanceType: opts.instanceType,\n dockerfilePath: opts.dockerfile,\n envFilePath: opts.envFile,\n imageRef: opts.imageRef,\n logVisibility: opts.logVisibility,\n gas: opts.gas,\n },\n logger,\n );\n\n return {\n tx: result.txHash,\n appId: result.appId,\n imageRef: result.imageRef,\n };\n },\n\n async logs(opts) {\n return logs(\n {\n privateKey,\n appID: opts.appID,\n watch: opts.watch,\n environment: ctx.environment,\n clientId: ctx.clientId,\n },\n logger,\n skipTelemetry, // Skip if called from CLI\n );\n },\n\n async start(appId, opts) {\n return withSDKTelemetry(\n {\n functionName: \"start\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n const pendingMessage = `Starting app ${appId}...`;\n\n const data = encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"startApp\",\n args: [appId],\n });\n\n const tx = await sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n to: environment.appControllerAddress as `0x${string}`,\n data,\n pendingMessage,\n txDescription: \"StartApp\",\n gas: opts?.gas,\n },\n logger,\n );\n return { tx };\n },\n );\n },\n\n async stop(appId, opts) {\n return withSDKTelemetry(\n {\n functionName: \"stop\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n const pendingMessage = `Stopping app ${appId}...`;\n\n const data = encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"stopApp\",\n args: [appId],\n });\n\n const tx = await sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n to: environment.appControllerAddress as `0x${string}`,\n data,\n pendingMessage,\n txDescription: \"StopApp\",\n gas: opts?.gas,\n },\n logger,\n );\n return { tx };\n },\n );\n },\n\n async terminate(appId, opts) {\n return withSDKTelemetry(\n {\n functionName: \"terminate\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n const pendingMessage = `Terminating app ${appId}...`;\n\n const data = encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"terminateApp\",\n args: [appId],\n });\n\n const tx = await sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n to: environment.appControllerAddress as `0x${string}`,\n data,\n pendingMessage,\n txDescription: \"TerminateApp\",\n gas: opts?.gas,\n },\n logger,\n );\n return { tx };\n },\n );\n },\n\n async isDelegated() {\n return isDelegated({\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n });\n },\n\n async undelegate() {\n return withSDKTelemetry(\n {\n functionName: \"undelegate\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n // perform the undelegate EIP7702 tx (sets delegated to zero address)\n const tx = await undelegate(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n },\n logger,\n );\n\n return { tx };\n },\n );\n },\n };\n}\n","/**\n * Environment configuration for different networks\n */\n\nimport { BillingEnvironmentConfig, EnvironmentConfig } from \"../types\";\n\n// Chain IDs\nexport const SEPOLIA_CHAIN_ID = 11155111;\nexport const MAINNET_CHAIN_ID = 1;\n\n// Common addresses across all chains\nexport const CommonAddresses: Record<string, string> = {\n ERC7702Delegator: \"0x63c0c19a282a1b52b07dd5a65b58948a07dae32b\",\n};\n\n// Addresses specific to each chain\nexport const ChainAddresses: Record<number, Record<string, string>> = {\n [MAINNET_CHAIN_ID]: {\n PermissionController: \"0x25E5F8B1E7aDf44518d35D5B2271f114e081f0E5\",\n },\n [SEPOLIA_CHAIN_ID]: {\n PermissionController: \"0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37\",\n },\n};\n\n// Billing environment configurations (separate from chain environments)\nconst BILLING_ENVIRONMENTS: Record<\"dev\" | \"prod\", BillingEnvironmentConfig> = {\n dev: {\n billingApiServerURL: \"https://billingapi-dev.eigencloud.xyz\",\n },\n prod: {\n billingApiServerURL: \"https://billingapi.eigencloud.xyz\",\n },\n};\n\n// Chain environment configurations\nconst ENVIRONMENTS: Record<string, Omit<EnvironmentConfig, \"chainID\">> = {\n \"sepolia-dev\": {\n name: \"sepolia\",\n build: \"dev\",\n appControllerAddress: \"0xa86DC1C47cb2518327fB4f9A1627F51966c83B92\",\n permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,\n erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,\n kmsServerURL: \"http://10.128.0.57:8080\",\n userApiServerURL: \"https://userapi-compute-sepolia-dev.eigencloud.xyz\",\n defaultRPCURL: \"https://ethereum-sepolia-rpc.publicnode.com\",\n },\n sepolia: {\n name: \"sepolia\",\n build: \"prod\",\n appControllerAddress: \"0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2\",\n permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,\n erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,\n kmsServerURL: \"http://10.128.15.203:8080\",\n userApiServerURL: \"https://userapi-compute-sepolia-prod.eigencloud.xyz\",\n defaultRPCURL: \"https://ethereum-sepolia-rpc.publicnode.com\",\n },\n \"mainnet-alpha\": {\n name: \"mainnet-alpha\",\n build: \"prod\",\n appControllerAddress: \"0xc38d35Fc995e75342A21CBd6D770305b142Fbe67\",\n permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,\n erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,\n kmsServerURL: \"http://10.128.0.2:8080\",\n userApiServerURL: \"https://userapi-compute.eigencloud.xyz\",\n defaultRPCURL: \"https://ethereum-rpc.publicnode.com\",\n },\n};\n\nconst CHAIN_ID_TO_ENVIRONMENT: Record<string, string> = {\n [SEPOLIA_CHAIN_ID.toString()]: \"sepolia\",\n [MAINNET_CHAIN_ID.toString()]: \"mainnet-alpha\",\n};\n\n/**\n * Get environment configuration\n */\nexport function getEnvironmentConfig(environment: string, chainID?: bigint): EnvironmentConfig {\n const env = ENVIRONMENTS[environment];\n if (!env) {\n throw new Error(`Unknown environment: ${environment}`);\n }\n\n // Check if environment is available in current build\n if (!isEnvironmentAvailable(environment)) {\n throw new Error(\n `Environment ${environment} is not available in this build type. ` +\n `Available environments: ${getAvailableEnvironments().join(\", \")}`,\n );\n }\n\n // If chainID provided, validate it matches\n if (chainID) {\n const expectedEnv = CHAIN_ID_TO_ENVIRONMENT[chainID.toString()];\n if (expectedEnv && expectedEnv !== environment) {\n throw new Error(`Environment ${environment} does not match chain ID ${chainID}`);\n }\n }\n\n // Determine chain ID from environment if not provided\n // Both \"sepolia\" and \"sepolia-dev\" use Sepolia chain ID\n const resolvedChainID =\n chainID ||\n (environment === \"sepolia\" || environment === \"sepolia-dev\"\n ? SEPOLIA_CHAIN_ID\n : MAINNET_CHAIN_ID);\n\n return {\n ...env,\n chainID: BigInt(resolvedChainID),\n };\n}\n\n/**\n * Get billing environment configuration\n * @param build - The build type (\"dev\" or \"prod\")\n */\nexport function getBillingEnvironmentConfig(build: \"dev\" | \"prod\"): {\n billingApiServerURL: string;\n} {\n const config = BILLING_ENVIRONMENTS[build];\n if (!config) {\n throw new Error(`Unknown billing environment: ${build}`);\n }\n return config;\n}\n\n/**\n * Detect environment from chain ID\n */\nexport function detectEnvironmentFromChainID(chainID: bigint): string | undefined {\n return CHAIN_ID_TO_ENVIRONMENT[chainID.toString()];\n}\n\n/**\n * Get build type from environment variable or build-time constant (defaults to 'prod')\n * BUILD_TYPE_BUILD_TIME is replaced at build time by tsup's define option\n */\n// @ts-ignore - BUILD_TYPE_BUILD_TIME is injected at build time by tsup\ndeclare const BUILD_TYPE_BUILD_TIME: string | undefined;\n\nexport function getBuildType(): \"dev\" | \"prod\" {\n // First check build-time constant (set by tsup define)\n // @ts-ignore - BUILD_TYPE_BUILD_TIME is injected at build time\n const buildTimeType =\n typeof BUILD_TYPE_BUILD_TIME !== \"undefined\" ? BUILD_TYPE_BUILD_TIME?.toLowerCase() : undefined;\n\n // Fall back to runtime environment variable\n const runtimeType = process.env.BUILD_TYPE?.toLowerCase();\n\n const buildType = buildTimeType || runtimeType;\n\n if (buildType === \"dev\") {\n return \"dev\";\n }\n return \"prod\";\n}\n\n/**\n * Get available environments based on build type\n * - dev: only \"sepolia-dev\"\n * - prod: \"sepolia\" and \"mainnet-alpha\"\n */\nexport function getAvailableEnvironments(): string[] {\n const buildType = getBuildType();\n\n if (buildType === \"dev\") {\n return [\"sepolia-dev\"];\n }\n\n // prod build\n return [\"sepolia\", \"mainnet-alpha\"];\n}\n\n/**\n * Check if an environment is available in the current build\n */\nexport function isEnvironmentAvailable(environment: string): boolean {\n return getAvailableEnvironments().includes(environment);\n}\n\n/**\n * Check if environment is mainnet (chain ID 1)\n */\nexport function isMainnet(environmentConfig: EnvironmentConfig): boolean {\n return environmentConfig.chainID === BigInt(MAINNET_CHAIN_ID);\n}\n","/**\n * Docker build operations\n */\n\nimport * as child_process from \"child_process\";\nimport { promisify } from \"util\";\nimport { DOCKER_PLATFORM } from \"../constants\";\nimport { Logger } from \"../types\";\n\nconst exec = promisify(child_process.exec);\n\n/**\n * Build Docker image using docker buildx\n * Streams output in real-time to logger\n */\nexport async function buildDockerImage(\n buildContext: string,\n dockerfilePath: string,\n tag: string,\n logger?: Logger,\n): Promise<void> {\n const args = [\n \"buildx\",\n \"build\",\n \"--platform\",\n DOCKER_PLATFORM,\n \"-t\",\n tag,\n \"-f\",\n dockerfilePath,\n \"--progress=plain\",\n buildContext,\n ];\n\n logger?.info(`Building Docker image: ${tag}`);\n logger?.info(``);\n\n return new Promise<void>((resolve, reject) => {\n const process = child_process.spawn(\"docker\", args, {\n cwd: buildContext,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n // Stream stdout to logger\n process.stdout?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stdout += output;\n // Log each line to info (Docker build output is important)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info(line);\n }\n });\n });\n\n // Stream stderr to logger\n process.stderr?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stderr += output;\n // Log each line to info (Docker build output is important)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info(line);\n }\n });\n });\n\n process.on(\"close\", (code) => {\n if (code !== 0) {\n const errorMessage = stderr || stdout || \"Unknown error\";\n reject(new Error(`Docker build failed: ${errorMessage}`));\n } else {\n resolve();\n }\n });\n\n process.on(\"error\", (error) => {\n reject(new Error(`Failed to start Docker build: ${error.message}`));\n });\n });\n}\n\n/**\n * Check if Docker is running\n */\nexport async function isDockerRunning(): Promise<boolean> {\n try {\n await exec(\"docker info\");\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Ensure Docker is running, throw error if not\n */\nexport async function ensureDockerIsRunning(): Promise<void> {\n const running = await isDockerRunning();\n if (!running) {\n throw new Error(\"Docker is not running. Please start Docker and try again.\");\n }\n}\n","/**\n * Constants used throughout the SDK\n */\n\nimport { sepolia, mainnet } from \"viem/chains\";\n\nexport const SUPPORTED_CHAINS = [mainnet, sepolia] as const;\n\nexport const DOCKER_PLATFORM = \"linux/amd64\";\nexport const REGISTRY_PROPAGATION_WAIT_SECONDS = 3;\nexport const LAYERED_DOCKERFILE_NAME = \"Dockerfile.eigencompute\";\nexport const ENV_SOURCE_SCRIPT_NAME = \"compute-source-env.sh\";\nexport const KMS_CLIENT_BINARY_NAME = \"kms-client\";\nexport const KMS_ENCRYPTION_KEY_NAME = \"kms-encryption-public-key.pem\";\nexport const KMS_SIGNING_KEY_NAME = \"kms-signing-public-key.pem\";\nexport const TLS_KEYGEN_BINARY_NAME = \"tls-keygen\";\nexport const CADDYFILE_NAME = \"Caddyfile\";\nexport const TEMP_IMAGE_PREFIX = \"ecloud-temp-\";\nexport const LAYERED_BUILD_DIR_PREFIX = \"ecloud-layered-build\";\nexport const SHA256_PREFIX = \"sha256:\";\nexport const JWT_FILE_PATH = \"/run/container_launcher/attestation_verifier_claims_token\";\n","/**\n * Docker image layering\n *\n * This module handles adding ecloud components to Docker images\n */\n\nimport Docker from \"dockerode\";\n\nimport * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport {\n extractImageConfig,\n checkIfImageAlreadyLayeredForECloud,\n pullDockerImage,\n} from \"./inspect\";\nimport { buildDockerImage } from \"./build\";\nimport { pushDockerImage } from \"./push\";\nimport { processDockerfileTemplate } from \"../templates/dockerfileTemplate\";\nimport { processScriptTemplate } from \"../templates/scriptTemplate\";\nimport { getKMSKeysForEnvironment } from \"../utils/keys\";\n\nimport {\n LAYERED_DOCKERFILE_NAME,\n ENV_SOURCE_SCRIPT_NAME,\n KMS_CLIENT_BINARY_NAME,\n KMS_SIGNING_KEY_NAME,\n TLS_KEYGEN_BINARY_NAME,\n CADDYFILE_NAME,\n LAYERED_BUILD_DIR_PREFIX,\n DOCKER_PLATFORM,\n} from \"../constants\";\n\nimport { getDirname } from \"../utils/dirname\";\n\nimport { EnvironmentConfig, Logger } from \"../types\";\n\n/**\n * Find binary file in tools directory\n * Supports both CLI (bundled) and standalone SDK usage\n */\nfunction findBinary(binaryName: string): string {\n const __dirname = getDirname();\n\n // Try to find SDK root by looking for tools directory\n // Start from current directory and walk up\n let currentDir = __dirname;\n const maxDepth = 10;\n let depth = 0;\n\n while (depth < maxDepth) {\n const toolsPath = path.join(currentDir, \"tools\", binaryName);\n if (fs.existsSync(toolsPath)) {\n return toolsPath;\n }\n\n // Also check if we're in a monorepo structure\n const sdkToolsPath = path.join(currentDir, \"packages\", \"sdk\", \"tools\", binaryName);\n if (fs.existsSync(sdkToolsPath)) {\n return sdkToolsPath;\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n break; // Reached filesystem root\n }\n currentDir = parentDir;\n depth++;\n }\n\n // Try relative paths as fallback\n const possiblePaths = [\n path.join(__dirname, \"../../../tools\", binaryName), // Standalone SDK from dist\n path.join(__dirname, \"../../../../tools\", binaryName), // CLI bundled\n path.join(__dirname, \"../../../../../tools\", binaryName), // Alternative CLI path\n path.resolve(__dirname, \"../../../../tools\", binaryName), // From source\n path.resolve(__dirname, \"../../../../../tools\", binaryName), // From source alternative\n ];\n\n for (const possiblePath of possiblePaths) {\n if (fs.existsSync(possiblePath)) {\n return possiblePath;\n }\n }\n\n // Return the most likely path for error messages\n return path.resolve(__dirname, \"../../../../tools\", binaryName);\n}\n\nexport interface BuildAndPushLayeredImageOptions {\n dockerfilePath: string;\n targetImageRef: string;\n logRedirect: string;\n resourceUsageAllow: string;\n envFilePath?: string;\n environmentConfig: EnvironmentConfig;\n}\n\nexport interface LayerRemoteImageIfNeededOptions {\n imageRef: string;\n logRedirect: string;\n resourceUsageAllow: string;\n envFilePath?: string;\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Build and push layered image from Dockerfile\n */\nexport async function buildAndPushLayeredImage(\n options: BuildAndPushLayeredImageOptions,\n logger: Logger,\n): Promise<string> {\n const {\n dockerfilePath,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n } = options;\n\n // 1. Build base image from user's Dockerfile\n const baseImageTag = `ecloud-temp-${path.basename(dockerfilePath).toLowerCase()}`;\n logger.info(`Building base image from ${dockerfilePath}...`);\n\n // Use the directory containing the Dockerfile as build context\n const buildContext = path.dirname(dockerfilePath);\n await buildDockerImage(buildContext, dockerfilePath, baseImageTag, logger);\n\n // 2. Layer the base image\n const docker = new Docker();\n return layerLocalImage(\n {\n docker,\n sourceImageRef: baseImageTag,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n}\n\n/**\n * Layer remote image if needed\n */\nexport async function layerRemoteImageIfNeeded(\n options: LayerRemoteImageIfNeededOptions,\n logger: Logger,\n): Promise<string> {\n const { imageRef, logRedirect, resourceUsageAllow, envFilePath, environmentConfig } = options;\n\n const docker = new Docker();\n\n // Check if image already has ecloud layering\n const alreadyLayered = await checkIfImageAlreadyLayeredForECloud(docker, imageRef);\n if (alreadyLayered) {\n logger.info(\"Image already has ecloud layering\");\n return imageRef;\n }\n\n // Pull image to ensure we have it locally\n logger.info(`Pulling image ${imageRef}...`);\n await pullDockerImage(docker, imageRef, DOCKER_PLATFORM, logger);\n\n // Prompt for target image (to avoid overwriting source)\n // TODO: Make this configurable via options\n const targetImageRef = `${imageRef}-layered`;\n\n logger.info(`Adding ecloud components to create ${targetImageRef} from ${imageRef}...`);\n const layeredImageRef = await layerLocalImage(\n {\n docker,\n sourceImageRef: imageRef,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n\n return layeredImageRef;\n}\n\n/**\n * Layer local image with ecloud components\n */\nasync function layerLocalImage(\n options: {\n docker: Docker;\n sourceImageRef: string;\n targetImageRef: string;\n logRedirect: string;\n resourceUsageAllow: string;\n envFilePath?: string;\n environmentConfig: EnvironmentConfig;\n },\n logger: Logger,\n): Promise<string> {\n const {\n docker,\n sourceImageRef,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n } = options;\n\n // 1. Extract original command and user from source image\n const imageConfig = await extractImageConfig(docker, sourceImageRef);\n const originalCmd = imageConfig.cmd.length > 0 ? imageConfig.cmd : imageConfig.entrypoint;\n const originalUser = imageConfig.user;\n\n // 2. Check if TLS is needed (check for DOMAIN in env file)\n let includeTLS = false;\n if (envFilePath && fs.existsSync(envFilePath)) {\n const envContent = fs.readFileSync(envFilePath, \"utf-8\");\n const domainMatch = envContent.match(/^DOMAIN=(.+)$/m);\n if (domainMatch && domainMatch[1] && domainMatch[1] !== \"localhost\") {\n includeTLS = true;\n logger.debug(`Found DOMAIN=${domainMatch[1]} in ${envFilePath}, including TLS components`);\n }\n }\n\n // 3. Generate template content\n const layeredDockerfileContent = processDockerfileTemplate({\n baseImage: sourceImageRef,\n originalCmd: JSON.stringify(originalCmd),\n originalUser: originalUser,\n logRedirect: logRedirect,\n resourceUsageAllow: resourceUsageAllow,\n includeTLS: includeTLS,\n ecloudCLIVersion: \"0.1.0\", // TODO: Get from package.json\n });\n\n const scriptContent = processScriptTemplate({\n kmsServerURL: environmentConfig.kmsServerURL,\n userAPIURL: environmentConfig.userApiServerURL,\n });\n\n // 4. Setup build directory\n const tempDir = await setupLayeredBuildDirectory(\n environmentConfig,\n layeredDockerfileContent,\n scriptContent,\n includeTLS,\n // logger\n );\n\n try {\n // 5. Build layered image\n logger.info(`Building updated image with ecloud components for ${sourceImageRef}...`);\n const layeredDockerfilePath = path.join(tempDir, LAYERED_DOCKERFILE_NAME);\n await buildDockerImage(tempDir, layeredDockerfilePath, targetImageRef, logger);\n\n // 6. Push to registry\n logger.info(`Publishing updated image to ${targetImageRef}...`);\n await pushDockerImage(docker, targetImageRef, logger);\n\n logger.info(`Successfully published updated image: ${targetImageRef}`);\n return targetImageRef;\n } finally {\n // Cleanup temp directory\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Setup layered build directory with all required files\n */\nasync function setupLayeredBuildDirectory(\n environmentConfig: EnvironmentConfig,\n layeredDockerfileContent: string,\n scriptContent: string,\n includeTLS: boolean,\n // logger?: Logger\n): Promise<string> {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), LAYERED_BUILD_DIR_PREFIX));\n\n try {\n // Write layered Dockerfile\n const layeredDockerfilePath = path.join(tempDir, LAYERED_DOCKERFILE_NAME);\n fs.writeFileSync(layeredDockerfilePath, layeredDockerfileContent, {\n mode: 0o644,\n });\n\n // Write wrapper script\n const scriptPath = path.join(tempDir, ENV_SOURCE_SCRIPT_NAME);\n fs.writeFileSync(scriptPath, scriptContent, { mode: 0o755 });\n\n // Copy KMS keys\n const { signingKey } = getKMSKeysForEnvironment(\n environmentConfig.name,\n environmentConfig.build,\n );\n\n const signingKeyPath = path.join(tempDir, KMS_SIGNING_KEY_NAME);\n fs.writeFileSync(signingKeyPath, signingKey, { mode: 0o644 });\n\n // Copy kms-client binary\n const kmsClientPath = path.join(tempDir, KMS_CLIENT_BINARY_NAME);\n const kmsClientSource = findBinary(\"kms-client-linux-amd64\");\n if (!fs.existsSync(kmsClientSource)) {\n throw new Error(\n `kms-client binary not found. Expected at: ${kmsClientSource}. ` +\n \"Make sure binaries are in packages/sdk/tools/ directory.\",\n );\n }\n fs.copyFileSync(kmsClientSource, kmsClientPath);\n fs.chmodSync(kmsClientPath, 0o755);\n\n // Include TLS components if requested\n if (includeTLS) {\n // Copy tls-keygen binary\n const tlsKeygenPath = path.join(tempDir, TLS_KEYGEN_BINARY_NAME);\n const tlsKeygenSource = findBinary(\"tls-keygen-linux-amd64\");\n if (!fs.existsSync(tlsKeygenSource)) {\n throw new Error(\n `tls-keygen binary not found. Expected at: ${tlsKeygenSource}. ` +\n \"Make sure binaries are in packages/sdk/tools/ directory.\",\n );\n }\n fs.copyFileSync(tlsKeygenSource, tlsKeygenPath);\n fs.chmodSync(tlsKeygenPath, 0o755);\n\n // Handle Caddyfile\n const caddyfilePath = path.join(process.cwd(), CADDYFILE_NAME);\n if (fs.existsSync(caddyfilePath)) {\n const caddyfileContent = fs.readFileSync(caddyfilePath);\n const destCaddyfilePath = path.join(tempDir, CADDYFILE_NAME);\n fs.writeFileSync(destCaddyfilePath, caddyfileContent, { mode: 0o644 });\n } else {\n throw new Error(\n \"TLS is enabled (DOMAIN is set) but Caddyfile not found. \" +\n \"Run configure TLS to set up TLS configuration\",\n );\n }\n }\n\n return tempDir;\n } catch (error) {\n // Cleanup on error\n fs.rmSync(tempDir, { recursive: true, force: true });\n throw error;\n }\n}\n","/**\n * Docker image inspection\n */\n\nimport Docker from \"dockerode\";\n\nimport { DockerImageConfig } from \"../types\";\n\n/**\n * Extract image configuration (CMD, ENTRYPOINT, USER)\n */\nexport async function extractImageConfig(\n docker: Docker,\n imageTag: string,\n): Promise<DockerImageConfig> {\n try {\n const image = docker.getImage(imageTag);\n const inspect = await image.inspect();\n\n const config = inspect.Config || {};\n const cmd = config.Cmd || [];\n const entrypoint = config.Entrypoint || [];\n const user = config.User || \"\";\n const labels = config.Labels || {};\n\n // Use CMD if available, otherwise use ENTRYPOINT\n const originalCmd = cmd.length > 0 ? cmd : entrypoint;\n\n return {\n cmd: originalCmd as string[],\n entrypoint: entrypoint as string[],\n user: user,\n labels: labels,\n };\n } catch (error: any) {\n throw new Error(`Failed to inspect image ${imageTag}: ${error.message}`);\n }\n}\n\n/**\n * Check if image already has ecloud layering\n */\nexport async function checkIfImageAlreadyLayeredForECloud(\n docker: Docker,\n imageTag: string,\n): Promise<boolean> {\n try {\n const config = await extractImageConfig(docker, imageTag);\n return \"eigenx_cli_version\" in config.labels;\n } catch {\n return false;\n }\n}\n\n/**\n * Pull Docker image\n */\nexport async function pullDockerImage(\n docker: Docker,\n imageTag: string,\n platform: string = \"linux/amd64\",\n logger?: { debug?: (msg: string) => void; info?: (msg: string) => void },\n): Promise<void> {\n logger?.info?.(`Pulling image ${imageTag}...`);\n\n return new Promise((resolve, reject) => {\n docker.pull(imageTag, { platform }, (err, stream) => {\n if (err) {\n reject(new Error(`Failed to pull image ${imageTag}: ${err.message}`));\n return;\n }\n\n // Must consume the stream to ensure pull completes\n docker.modem.followProgress(\n stream!,\n (err) => {\n if (err) {\n reject(new Error(`Failed to complete image pull for ${imageTag}: ${err.message}`));\n } else {\n logger?.info?.(`Image pull completed: ${imageTag}`);\n resolve();\n }\n },\n (event: any) => {\n // Log progress events\n if (event && event.status) {\n logger?.info?.(event.status);\n }\n },\n );\n });\n });\n}\n","/**\n * Docker push operations\n */\n\nimport Docker from \"dockerode\";\n\nimport * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\nimport * as child_process from \"child_process\";\n\nimport { exec } from \"child_process\";\nimport { promisify } from \"util\";\n\nconst execAsync = promisify(exec);\n\n/**\n * Extract hostname from a registry URL/string for safe comparison\n */\nfunction extractHostname(registry: string): string {\n let hostname = registry.replace(/^https?:\\/\\//, \"\");\n hostname = hostname.split(\"/\")[0];\n hostname = hostname.split(\":\")[0];\n return hostname.toLowerCase();\n}\n\n/**\n * Check if a registry matches Docker Hub\n */\nfunction isDockerHub(registry: string): boolean {\n const hostname = extractHostname(registry);\n return (\n hostname === \"docker.io\" ||\n hostname === \"index.docker.io\" ||\n hostname === \"registry-1.docker.io\"\n );\n}\n\n/**\n * Check if a registry matches Google Container Registry\n */\nfunction isGCR(registry: string): boolean {\n const hostname = extractHostname(registry);\n return hostname === \"gcr.io\" || hostname.endsWith(\".gcr.io\");\n}\n\n/**\n * Extract registry from image reference\n */\nexport function extractRegistry(imageRef: string): string {\n // Handle different registry formats:\n // - docker.io/library/image:tag\n // - ghcr.io/owner/image:tag\n // - gcr.io/project/image:tag\n // - registry.example.com/image:tag\n\n const parts = imageRef.split(\"/\");\n if (parts.length < 2) {\n return \"docker.io\"; // Default to Docker Hub\n }\n\n const firstPart = parts[0];\n\n // Check if first part is a registry (contains . or is a known registry)\n if (firstPart.includes(\".\") || firstPart === \"ghcr.io\" || isGCR(firstPart)) {\n return firstPart;\n }\n\n // Default to Docker Hub\n return \"docker.io\";\n}\n\n/**\n * Get auth config for a specific registry\n * Returns an object with username/password or auth string\n * Handles both direct auth in config.json and credential stores\n */\nexport async function getRegistryAuthConfig(\n registry: string,\n): Promise<{ username?: string; password?: string; auth?: string } | undefined> {\n const authConfig = getDockerAuthConfig();\n\n // Helper to extract auth from config entry\n const extractAuth = (auth: any) => {\n if (!auth) return undefined;\n // If auth string exists, use it\n if (auth.auth) {\n return { auth: auth.auth };\n }\n // If username and password exist, use them\n if (auth.username && auth.password) {\n return { username: auth.username, password: auth.password };\n }\n return undefined;\n };\n\n // Try exact match first\n const exactMatch = extractAuth(authConfig[registry]);\n if (exactMatch) return exactMatch;\n\n // Try with https:// prefix\n const httpsRegistry = `https://${registry}`;\n const httpsMatch = extractAuth(authConfig[httpsRegistry]);\n if (httpsMatch) return httpsMatch;\n\n // For ghcr.io, also try common variants\n if (registry === \"ghcr.io\") {\n const ghcrVariants = [\"ghcr.io\", \"https://ghcr.io\", \"https://ghcr.io/v1/\"];\n for (const variant of ghcrVariants) {\n const match = extractAuth(authConfig[variant]);\n if (match) return match;\n\n // If entry exists but is empty (credential store), try to get from helper\n if (authConfig[variant] && Object.keys(authConfig[variant]).length === 0) {\n const creds = await getCredentialsFromHelper(\"ghcr.io\");\n if (creds) {\n return { username: creds.username, password: creds.password };\n }\n }\n }\n\n // Also try to get from helper even if no entry exists (for credential store only setups)\n const creds = await getCredentialsFromHelper(\"ghcr.io\");\n if (creds) {\n return { username: creds.username, password: creds.password };\n }\n }\n\n // For Docker Hub, try common variants\n if (isDockerHub(registry)) {\n const dockerVariants = [\n \"https://index.docker.io/v1/\",\n \"https://index.docker.io/v1\",\n \"index.docker.io\",\n \"docker.io\",\n ];\n for (const variant of dockerVariants) {\n const match = extractAuth(authConfig[variant]);\n if (match) return match;\n }\n }\n\n return undefined;\n}\n\n/**\n * Push Docker image to registry\n * Uses Docker CLI directly for better credential helper support\n * Streams output in real-time to logger\n */\nexport async function pushDockerImage(\n docker: Docker,\n imageRef: string,\n logger?: { debug?: (msg: string) => void; info?: (msg: string) => void },\n): Promise<void> {\n // Use Docker CLI directly instead of dockerode for better credential helper support\n // Docker CLI automatically handles credential helpers, which dockerode sometimes struggles with\n logger?.info?.(`Pushing image ${imageRef}...`);\n\n return new Promise<void>((resolve, reject) => {\n const process = child_process.spawn(\"docker\", [\"push\", imageRef], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n // Stream stdout to logger\n process.stdout?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stdout += output;\n // Log each line to info (Docker push output shows progress)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info?.(line);\n }\n });\n });\n\n // Stream stderr to logger\n process.stderr?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stderr += output;\n // Log each line to info (Docker push output shows progress)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info?.(line);\n }\n });\n });\n\n process.on(\"close\", async (code) => {\n if (code !== 0) {\n const errorMsg = stderr || stdout || \"Unknown error\";\n if (isPermissionError(errorMsg)) {\n reject(new PushPermissionError(imageRef, new Error(errorMsg)));\n } else {\n reject(new Error(`Docker push failed: ${errorMsg}`));\n }\n return;\n }\n\n // Check for success indicators\n const output = stdout + stderr;\n if (!output.includes(\"digest:\") && !output.includes(\"pushed\") && !output.includes(\"Pushed\")) {\n logger?.debug?.(\"No clear success indicator in push output, verifying...\");\n }\n\n logger?.info?.(\"Image push completed successfully\");\n\n // Verify the push by checking if image exists in registry\n // Wait a bit longer for GHCR to process\n try {\n await verifyImageExists(imageRef, logger);\n resolve();\n } catch (error: any) {\n reject(error);\n }\n });\n\n process.on(\"error\", (error) => {\n const msg = error.message || String(error);\n if (msg.includes(\"command not found\") || msg.includes(\"ENOENT\")) {\n reject(\n new Error(`Docker CLI not found. Please ensure Docker is installed and in your PATH.`),\n );\n } else {\n reject(new Error(`Failed to start Docker push: ${msg}`));\n }\n });\n });\n}\n\n/**\n * Verify that the image exists in the registry after push\n */\nasync function verifyImageExists(\n imageRef: string,\n logger?: { debug?: (msg: string) => void; info?: (msg: string) => void },\n): Promise<void> {\n // Wait longer for registry to process (GHCR can be slow)\n logger?.debug?.(\"Waiting for registry to process image...\");\n await new Promise((resolve) => setTimeout(resolve, 3000));\n\n // Retry verification up to 5 times with increasing delays\n let retries = 5;\n\n while (retries > 0) {\n try {\n await execAsync(`docker manifest inspect ${imageRef}`, {\n maxBuffer: 10 * 1024 * 1024,\n timeout: 10000, // 10 second timeout\n });\n // If we get here, the image exists\n logger?.debug?.(\"Image verified in registry\");\n return;\n } catch (error: any) {\n const errorMsg = error.message || String(error);\n\n // If manifest inspect fails, wait and retry\n if (errorMsg.includes(\"manifest unknown\") || errorMsg.includes(\"not found\")) {\n retries--;\n if (retries > 0) {\n const waitTime = (6 - retries) * 2000; // 2s, 4s, 6s, 8s, 10s\n logger?.debug?.(\n `Image not found yet, retrying in ${waitTime / 1000}s... (${retries} retries left)`,\n );\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n continue;\n }\n // All retries exhausted\n throw new Error(\n `Image push verification failed: Image ${imageRef} was not found in registry after multiple attempts.\\n` +\n `This usually means the push failed. Please check:\\n` +\n `1. Your authentication: docker login ghcr.io\\n` +\n `2. Your permissions: Ensure you have push access to the repository\\n` +\n `3. Try pushing manually: docker push ${imageRef}\\n` +\n `4. Check if the image exists: docker manifest inspect ${imageRef}`,\n );\n }\n // Other errors might be temporary (network issues, etc.)\n // Retry once more\n retries--;\n if (retries > 0) {\n await new Promise((resolve) => setTimeout(resolve, 2000));\n continue;\n }\n // Log a warning but don't fail for non-manifest-unknown errors\n logger?.debug?.(`Warning: Could not verify image push: ${errorMsg}`);\n return;\n }\n }\n}\n\n/**\n * Check if error message indicates a permission/auth issue\n */\nfunction isPermissionError(errMsg: string): boolean {\n const errLower = errMsg.toLowerCase();\n const permissionKeywords = [\n \"denied\",\n \"unauthorized\",\n \"forbidden\",\n \"insufficient_scope\",\n \"authentication required\",\n \"access forbidden\",\n \"permission denied\",\n \"requested access to the resource is denied\",\n ];\n\n return permissionKeywords.some((keyword) => errLower.includes(keyword));\n}\n\n/**\n * Push permission error class\n */\nexport class PushPermissionError extends Error {\n constructor(\n public imageRef: string,\n public originalError: Error,\n ) {\n super(`Permission denied pushing to ${imageRef}: ${originalError.message}`);\n this.name = \"PushPermissionError\";\n }\n}\n\n/**\n * Get Docker auth config from system\n * This reads from ~/.docker/config.json and handles credential stores\n */\nexport function getDockerAuthConfig(): Record<string, any> {\n const dockerConfigPath = path.join(os.homedir(), \".docker\", \"config.json\");\n\n if (!fs.existsSync(dockerConfigPath)) {\n return {};\n }\n\n try {\n const config = JSON.parse(fs.readFileSync(dockerConfigPath, \"utf-8\"));\n const auths = config.auths || {};\n\n // If credsStore is set, credentials are stored in credential helper (e.g., osxkeychain)\n // In this case, dockerode should handle auth automatically, but we still return\n // the auths structure (even if empty) to indicate the registry is configured\n if (config.credsStore) {\n // Return auths as-is (may be empty objects, but registry is configured)\n return auths;\n }\n\n return auths;\n } catch {\n return {};\n }\n}\n\n/**\n * Get credentials from Docker credential helper\n */\nasync function getCredentialsFromHelper(\n registry: string,\n): Promise<{ username: string; password: string } | undefined> {\n const dockerConfigPath = path.join(os.homedir(), \".docker\", \"config.json\");\n\n if (!fs.existsSync(dockerConfigPath)) {\n return undefined;\n }\n\n try {\n const config = JSON.parse(fs.readFileSync(dockerConfigPath, \"utf-8\"));\n const credsStore = config.credsStore;\n\n if (!credsStore) {\n return undefined;\n }\n\n // Use Docker credential helper to get credentials\n // Format: docker-credential-<helper> get <serverURL>\n const { execSync } = await import(\"child_process\");\n const helper = `docker-credential-${credsStore}`;\n\n try {\n const output = execSync(`echo \"${registry}\" | ${helper} get`, {\n encoding: \"utf-8\",\n });\n const creds = JSON.parse(output);\n if (creds.Username && creds.Secret) {\n return { username: creds.Username, password: creds.Secret };\n }\n } catch {\n // Credential helper failed, return undefined\n return undefined;\n }\n } catch {\n return undefined;\n }\n\n return undefined;\n}\n","import Handlebars from \"handlebars\";\nimport dockerfileTemplate from \"./Dockerfile.layered.tmpl\";\n\nexport interface DockerfileTemplateData {\n baseImage: string;\n originalCmd: string; // JSON array string\n originalUser: string;\n logRedirect: string;\n resourceUsageAllow: string; // \"always\" or \"never\" for memory monitoring\n includeTLS: boolean;\n ecloudCLIVersion: string;\n}\n\n/**\n * Process Dockerfile template\n */\nexport function processDockerfileTemplate(data: DockerfileTemplateData): string {\n const template = Handlebars.compile(dockerfileTemplate);\n return template(data);\n}\n","{{#if includeTLS}}\n# Get Caddy from official image\nFROM caddy:2.10.2-alpine AS caddy\n{{/if}}\n\nFROM {{baseImage}}\n\n{{#if originalUser}}\n# Switch to root to perform setup (base image has non-root USER: {{originalUser}})\nUSER root\n{{/if}}\n\n# Copy core TEE components\nCOPY compute-source-env.sh /usr/local/bin/\nCOPY kms-client /usr/local/bin/\nCOPY kms-signing-public-key.pem /usr/local/bin/\n\n{{#if includeTLS}}\n# Copy Caddy from official image\nCOPY --from=caddy /usr/bin/caddy /usr/local/bin/caddy\n\n# Copy TLS components\nCOPY tls-keygen /usr/local/bin/\nCOPY Caddyfile /etc/caddy/\n{{/if}}\n\n{{#if originalUser}}\n# Make binaries executable (755 for executables, 644 for keys)\nRUN chmod 755 /usr/local/bin/compute-source-env.sh \\\n && chmod 755 /usr/local/bin/kms-client{{#if includeTLS}} \\\n && chmod 755 /usr/local/bin/tls-keygen \\\n && chmod 755 /usr/local/bin/caddy{{/if}} \\\n && chmod 644 /usr/local/bin/kms-signing-public-key.pem\n\n# Store original user - entrypoint will drop privileges to this user after TEE setup\nENV __ECLOUD_ORIGINAL_USER={{originalUser}}\n{{else}}\n# Make binaries executable (preserve existing permissions, just add execute)\nRUN chmod +x /usr/local/bin/compute-source-env.sh \\\n && chmod +x /usr/local/bin/kms-client{{#if includeTLS}} \\\n && chmod +x /usr/local/bin/tls-keygen{{/if}}\n{{/if}}\n\n{{#if logRedirect}}\n\nLABEL tee.launch_policy.log_redirect={{logRedirect}}\n{{/if}}\n{{#if resourceUsageAllow}}\n\nLABEL tee.launch_policy.monitoring_memory_allow={{resourceUsageAllow}}\n{{/if}}\n\nLABEL eigenx_cli_version={{ecloudCLIVersion}}\nLABEL eigenx_use_ita=True\n\n{{#if includeTLS}}\n# Expose both HTTP and HTTPS ports for Caddy\nEXPOSE 80 443\n{{/if}}\n\nENTRYPOINT [\"/usr/local/bin/compute-source-env.sh\"]\nCMD {{{originalCmd}}}\n","import Handlebars from \"handlebars\";\nimport scriptTemplate from \"./compute-source-env.sh.tmpl\";\n\nexport interface ScriptTemplateData {\n kmsServerURL: string;\n userAPIURL: string;\n}\n\n/**\n * Process script template\n */\nexport function processScriptTemplate(data: ScriptTemplateData): string {\n const template = Handlebars.compile(scriptTemplate);\n return template(data);\n}\n","#!/bin/sh\necho \"compute-source-env.sh: Running setup script...\"\n\n# Fetch and source environment variables from KMS\necho \"Fetching secrets from KMS...\"\nif /usr/local/bin/kms-client \\\n --kms-server-url \"{{kmsServerURL}}\" \\\n --kms-signing-key-file /usr/local/bin/kms-signing-public-key.pem \\\n --userapi-url \"{{userAPIURL}}\" \\\n --output /tmp/.env; then\n echo \"compute-source-env.sh: Successfully fetched environment variables from KMS\"\n set -a && . /tmp/.env && set +a\n rm -f /tmp/.env\nelse\n echo \"compute-source-env.sh: ERROR - Failed to fetch environment variables from KMS\"\n echo \"compute-source-env.sh: Exiting - cannot start user workload without KMS secrets\"\n exit 1\nfi\n\n# Setup TLS if tls-keygen is present (which means TLS was configured at build time)\nsetup_tls() {\n # If tls-keygen isn't present, TLS wasn't configured during build\n if [ ! -x /usr/local/bin/tls-keygen ]; then\n echo \"compute-source-env.sh: TLS not configured (no tls-keygen binary)\"\n return 0\n fi\n \n local domain=\"${DOMAIN:-}\"\n local mnemonic=\"${MNEMONIC:-}\"\n \n # Since tls-keygen is present, TLS is expected - validate requirements\n if [ -z \"$domain\" ] || [ \"$domain\" = \"localhost\" ]; then\n echo \"compute-source-env.sh: ERROR - TLS binary present but DOMAIN not configured or is localhost\"\n echo \"compute-source-env.sh: Set DOMAIN environment variable to a valid domain\"\n exit 1\n fi\n \n if [ -z \"$mnemonic\" ]; then\n echo \"compute-source-env.sh: ERROR - TLS binary present but MNEMONIC not available\"\n echo \"compute-source-env.sh: Cannot obtain TLS certificate without mnemonic\"\n exit 1\n fi\n \n if [ ! -x /usr/local/bin/caddy ]; then\n echo \"compute-source-env.sh: ERROR - TLS binary present but Caddy not found\"\n exit 1\n fi\n \n echo \"compute-source-env.sh: Setting up TLS for domain: $domain\"\n \n # Obtain TLS certificate using ACME\n # Default to http-01, but allow override via ACME_CHALLENGE env var\n local challenge=\"${ACME_CHALLENGE:-http-01}\"\n \n # Check if we should use staging (for testing)\n local staging_flag=\"\"\n if [ \"${ACME_STAGING:-false}\" = \"true\" ]; then\n staging_flag=\"-staging\"\n echo \"compute-source-env.sh: Using Let's Encrypt STAGING environment (certificates won't be trusted)\"\n fi\n \n echo \"compute-source-env.sh: Obtaining TLS certificate using $challenge challenge...\"\n # Pass the API URL for certificate persistence\n if ! MNEMONIC=\"$mnemonic\" DOMAIN=\"$domain\" API_URL=\"{{userAPIURL}}\" /usr/local/bin/tls-keygen \\\n -challenge \"$challenge\" \\\n $staging_flag; then\n echo \"compute-source-env.sh: ERROR - Failed to obtain TLS certificate\"\n echo \"compute-source-env.sh: Certificate issuance failed for $domain\"\n exit 1\n fi\n \n echo \"compute-source-env.sh: TLS certificate obtained successfully\"\n \n # Validate Caddyfile before starting\n if ! /usr/local/bin/caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile 2>/dev/null; then\n echo \"compute-source-env.sh: ERROR - Invalid Caddyfile\"\n echo \"compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed\"\n exit 1\n fi\n \n # Start Caddy in background\n echo \"compute-source-env.sh: Starting Caddy reverse proxy...\"\n \n # Check if Caddy logs should be enabled\n if [ \"${ENABLE_CADDY_LOGS:-false}\" = \"true\" ]; then\n if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile 2>&1; then\n echo \"compute-source-env.sh: ERROR - Failed to start Caddy\"\n echo \"compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed\"\n exit 1\n fi\n else\n # Redirect Caddy output to /dev/null to silence logs\n if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1; then\n echo \"compute-source-env.sh: ERROR - Failed to start Caddy\"\n echo \"compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed\"\n exit 1\n fi\n fi\n \n # Give Caddy a moment to fully initialize\n sleep 2\n echo \"compute-source-env.sh: Caddy started successfully\"\n return 0\n}\n\n# Run TLS setup\nsetup_tls\n\necho \"compute-source-env.sh: Environment sourced.\"\n\n# Drop privileges to original user for the application command\nif [ -n \"$__ECLOUD_ORIGINAL_USER\" ] && [ \"$(id -u)\" = \"0\" ]; then\n echo \"compute-source-env.sh: Dropping privileges to user: $__ECLOUD_ORIGINAL_USER\"\n exec su -s /bin/sh \"$__ECLOUD_ORIGINAL_USER\" -c 'exec \"$@\"' -- sh \"$@\"\nfi\n\nexec \"$@\"\n","-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kHU86k17ofCIGcJKDcf\nAFurFhSLeWmOL0bwWLCeVnTPG0MMHtJOq+woE0XXSWw6lzm+jzavBBTwKde1dgal\nAp91vULAZFMUpiUdd2dNUVtvU89qW0Pgf1Eu5FDj7BkY/SnyECbWJM4ga0BmpiGy\nnQwLNN9mMGhjVoVLn2zwEGZ7JzS9Nz11EZKO/k/9DcO6LaoIFmKuvVf3jl6lvZg8\naeA0LoZXjkycHlRUt/kfKwZnhakUaYHP1ksV7ZNmolS5GYDTSKGB2KPPNR1s4/Xu\nu8zeEFC8HuGRU8XuuBeaAunitnGhbNVREUNJGff6HZOGB6CIFNXjbQETeZ3p5uro\n0v+hd1QqQYBv7+DEaMCmGnJNGAyIMr2mn4vr7wGsIj0HonlSHmQ8rmdUhL2ocNTc\nLhKgZiZmBuDpSbFW/r53R2G7CHcqaqGeUBnT54QCH4zsYKw0/4dOtwFxQpTyBf9/\n+k+KaWEJYKkx9d9OzKGyAvzrTDVOFoajddiJ6LPvRlMdOUQr3hl4IAC0/nh9lhHq\nD0R+i5WAU96TkdAe7B7iTGH2D22k0KUPR6Q9W3aF353SLxQAMPNrgG4QQufAdRJn\nAF+8ntun5TkTqjTWRSwAsUJZ1z4wb96DympWJbDi0OciJRZ3Fz3j9+amC43yCHGg\naaEMjdt35ewbztUSc04F10MCAwEAAQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfxbhXJjH4D0DH/iW5/rK1HzWS+f9\nEyooZTrCYjCfezuOEmRuOWNaZLvwXN8SdzrvjWA7gSvOS85hLzp4grANRQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr/vqttU6aXX35HtsXavU\n5teysunDzZB3HyaFM4qcuRnqj+70KxqLOwZsERN5SwZ/56Jm8T2ds1CcXsQCMUMw\n+MPlsF6KMGfzghLtYHONwvKLnn+U9y886aAay6W8a0A7O7YCZehNYD3kQnCXjOIc\nMj6v8AEvMw+w/lNabjRXnwSBMKVIGp/cSL0hGwt8fGoC3TsxQN9opzvU1Z4rAw9K\na119l6dlPnqezDva378TCaXDjqKe/jSZOI1CcYpaSK2SJ+95Wbvte5j3lXbg1oT2\n0rXeJUHEJ68QxMtJplfw0Sg+Ek4CUJ2c/kbdg0u7sIIO5wcB4WHL/Lfbw2XPmcBI\nt0r0EC575D3iHF/aI01Ms2IRA0GDeHnNcr5FJLWJljTjNLEt4tFITrXwBe1Ealm3\nNCxamApl5bBSwQ72Gb5fiQFwB8Fl2/XG3wfGTFInFEvWE4c/H8dtu1wHTsyEFZcG\nB47IkD5GBSZq90Hd9xuZva55dxGpqUVrEJO88SqHGP9Oa+HLTYdEe5AR5Hitw4Mu\ndk1cCH+X5OqY9dfpdoCNbKAM0N2SJvNAnDTU2JKGYheXrnDslXR6atBmU5gDkH+W\nQVryDYl9xbwWIACMQsAQjrrtKw5xqJ4V89+06FN/wyEVF7KWAcJ4AhKiVnCvLqzb\nBbISc+gOkRsefhCDJVPEKDkCAwEAAQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEb2Q88/cxdic2xi4jS2V0dtYHjLwq\n4wVFBFmaY8TTXoMXNggKEdU6PuE8EovocVKMpw3SIlaM27z9uxksNVL2xw==\n-----END PUBLIC KEY-----\n","-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApDvk8pAivkgtiC5li5MP\nxMTJDduTeorBl18ynrooTxp2BwwgPwXfXbJaCA0qRubvc0aO2uh2VDrPM27CqMLH\no2S9YLtpLii4A1Nl7SE/MdWKWdG6v94xNGpc2YyPP7yWtHfqOkgDWp8sokl3Uq/9\nMS0pjUaI7RyS5boCTy8Qw90BxGMpucjOmqm+luw4EdPWZCrgriUR2bbGRRgAmrT1\nK4ou4IgPp799r120hwHbCWxnOvLdQdpiv2507b900xS/3yZahhnHCAn66146LU/f\nBrRpQKSM0qSpktXrrc9MH/ru2VLR5cGLp89ZcZMQA9cRGglWM5XWVY3Ti2TPJ6Kd\nAn1d7qNkGJaSdVa3x3HkOf6c6HeTyqis5/L/6L+PFhUsTRbmKg1FtwD+3xxdyf7h\nabFxryE9rv+WatHL6r6z5ztV0znJ/Fpfs5A45FWA6pfb28fA59RGpi/DQ8RxgdCH\nnZRNvdz8dTgRaXSPgkfGXBcCFqb/QhFmad7XbWDthGzfhbPOxNPtiaGRQ1Dr/Pgq\nn0ugdLbRQLmDOAFgaQcnr0U4y1TUlWJnvoZMETkVN7gmITtXA4F324ALT7Rd+Lgk\nHikW5vG+NjAEwXfPsK0YzT+VbHd7o1lbru9UxiDlN03XVEkz/oRQi47CvSTo3FSr\n5dB4lz8kov3UUcNJfQFZolMCAwEAAQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsk6ZdmmvBqFfKHs+1cYjIemRGN7h\n1NatIEitFRyx+3q8wmTJ9LknTE1FwWBLcCNTseJDti8Rh+SaVxfGOyJuuA==\n-----END PUBLIC KEY-----","/**\n * KMS key loading utilities\n */\n\n// Import all keys at build time\nimport mainnetAlphaProdEncryption from \"../../../../keys/mainnet-alpha/prod/kms-encryption-public-key.pem\";\nimport mainnetAlphaProdSigning from \"../../../../keys/mainnet-alpha/prod/kms-signing-public-key.pem\";\nimport sepoliaDevEncryption from \"../../../../keys/sepolia/dev/kms-encryption-public-key.pem\";\nimport sepoliaDevSigning from \"../../../../keys/sepolia/dev/kms-signing-public-key.pem\";\nimport sepoliaProdEncryption from \"../../../../keys/sepolia/prod/kms-encryption-public-key.pem\";\nimport sepoliaProdSigning from \"../../../../keys/sepolia/prod/kms-signing-public-key.pem\";\n\ntype KeyMap = {\n [environment: string]: {\n [build: string]: {\n encryption: string;\n signing: string;\n };\n };\n};\n\nconst KEYS: KeyMap = {\n \"mainnet-alpha\": {\n prod: {\n encryption: mainnetAlphaProdEncryption,\n signing: mainnetAlphaProdSigning,\n },\n },\n sepolia: {\n dev: {\n encryption: sepoliaDevEncryption,\n signing: sepoliaDevSigning,\n },\n prod: {\n encryption: sepoliaProdEncryption,\n signing: sepoliaProdSigning,\n },\n },\n};\n\n/**\n * Get KMS keys for environment\n */\nexport function getKMSKeysForEnvironment(\n environment: string,\n build: \"dev\" | \"prod\" = \"prod\",\n): { encryptionKey: Buffer; signingKey: Buffer } {\n const envKeys = KEYS[environment];\n if (!envKeys) {\n throw new Error(`No keys found for environment: ${environment}`);\n }\n\n const buildKeys = envKeys[build];\n if (!buildKeys) {\n throw new Error(`No keys found for environment: ${environment}, build: ${build}`);\n }\n\n return {\n encryptionKey: Buffer.from(buildKeys.encryption),\n signingKey: Buffer.from(buildKeys.signing),\n };\n}\n\n/**\n * Check if keys exist for environment\n */\nexport function keysExistForEnvironment(\n environment: string,\n build: \"dev\" | \"prod\" = \"prod\",\n): boolean {\n return !!KEYS[environment]?.[build];\n}\n","/**\n * ESM and CJS compatible getDirname utility\n */\n\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Get __dirname equivalent that works in both ESM and CJS\n * In CJS builds, __dirname is available and will be used\n * In ESM builds, import.meta.url is used\n */\nexport function getDirname(): string {\n // Check for CJS __dirname first (available in CommonJS)\n if (typeof __dirname !== \"undefined\") {\n return __dirname;\n }\n\n // For ESM, we need to use import.meta.url\n // This will be evaluated at build time by tsup for ESM builds\n // For CJS builds, the above check will catch it, so this won't execute\n try {\n const metaUrl = import.meta.url;\n return path.dirname(fileURLToPath(metaUrl));\n } catch {\n // Fallback (shouldn't reach here in normal usage)\n return process.cwd();\n }\n}\n","/**\n * Image registry operations - digest extraction\n *\n * Uses Docker API to extract image digest and validate platform\n */\n\nimport * as child_process from \"child_process\";\nimport { promisify } from \"util\";\nimport { ImageDigestResult } from \"../types\";\nimport { DOCKER_PLATFORM } from \"../constants\";\n\nconst execFileAsync = promisify(child_process.execFile);\n\ninterface Platform {\n os: string;\n architecture: string;\n}\n\ninterface ManifestManifest {\n digest: string;\n platform?: Platform;\n}\n\ninterface Manifest {\n manifests?: ManifestManifest[];\n config?: {\n digest: string;\n };\n mediaType?: string;\n}\n\n/**\n * Get image digest and registry name from image reference\n * Uses docker manifest inspect to get the manifest\n */\nexport async function getImageDigestAndName(imageRef: string): Promise<ImageDigestResult> {\n try {\n // Use docker manifest inspect to get the manifest safely\n const { stdout } = await execFileAsync(\n \"docker\",\n [\"manifest\", \"inspect\", imageRef],\n { maxBuffer: 10 * 1024 * 1024 }, // 10MB buffer\n );\n\n const manifest: Manifest = JSON.parse(stdout);\n\n // Check if it's a multi-platform manifest (index)\n if (manifest.manifests && manifest.manifests.length > 0) {\n return extractDigestFromMultiPlatform(manifest, imageRef);\n } else {\n // Single-platform image\n return extractDigestFromSinglePlatform(manifest, imageRef);\n }\n } catch (error: any) {\n throw new Error(`Failed to get image digest for ${imageRef}: ${error.message}`);\n }\n}\n\n/**\n * Extract digest from multi-platform image index\n */\nfunction extractDigestFromMultiPlatform(manifest: Manifest, imageRef: string): ImageDigestResult {\n if (!manifest.manifests) {\n throw new Error(`Invalid manifest for ${imageRef}: no manifests found`);\n }\n\n const platforms: string[] = [];\n\n for (const m of manifest.manifests) {\n if (m.platform) {\n const platform = `${m.platform.os}/${m.platform.architecture}`;\n platforms.push(platform);\n\n if (platform === DOCKER_PLATFORM) {\n const digest = hexStringToBytes32(m.digest);\n const registry = extractRegistryName(imageRef);\n return {\n digest,\n registry,\n platform: DOCKER_PLATFORM,\n };\n }\n }\n }\n\n // No compatible platform found\n throw createPlatformErrorMessage(imageRef, platforms);\n}\n\n/**\n * Extract digest from single-platform image\n * For single-platform images, we need to inspect the image config\n */\nasync function extractDigestFromSinglePlatform(\n manifest: Manifest,\n imageRef: string,\n): Promise<ImageDigestResult> {\n // For single-platform images, we need to get the config digest\n // and then inspect the image to get platform info\n try {\n // Use docker inspect to get platform info\n const { stdout } = await execFileAsync(\"docker\", [\"inspect\", imageRef], {\n maxBuffer: 10 * 1024 * 1024,\n });\n\n const inspectData = JSON.parse(stdout);\n if (!inspectData || !inspectData[0]) {\n throw new Error(`Failed to inspect image ${imageRef}`);\n }\n\n const config = inspectData[0].Architecture\n ? {\n os: inspectData[0].Os || \"linux\",\n architecture: inspectData[0].Architecture,\n }\n : null;\n\n if (!config) {\n // Try to get from manifest config digest\n if (manifest.config?.digest) {\n const digest = hexStringToBytes32(manifest.config.digest);\n const registry = extractRegistryName(imageRef);\n // Assume linux/amd64 if we can't determine platform\n return {\n digest,\n registry,\n platform: DOCKER_PLATFORM,\n };\n }\n throw new Error(`Could not determine platform for ${imageRef}`);\n }\n\n const platform = `${config.os}/${config.architecture}`;\n\n if (platform === DOCKER_PLATFORM) {\n // Get digest from RepoDigests or use config digest\n let digest: Uint8Array;\n if (inspectData[0].RepoDigests && inspectData[0].RepoDigests.length > 0) {\n const repoDigest = inspectData[0].RepoDigests[0];\n digest = extractDigestFromRepoDigest(repoDigest);\n } else if (manifest.config?.digest) {\n digest = hexStringToBytes32(manifest.config.digest);\n } else {\n throw new Error(`Could not extract digest for ${imageRef}`);\n }\n\n const registry = extractRegistryName(imageRef);\n return {\n digest,\n registry,\n platform: DOCKER_PLATFORM,\n };\n }\n\n // Platform mismatch\n throw createPlatformErrorMessage(imageRef, [platform]);\n } catch (error: any) {\n if (error.message.includes(\"platform\")) {\n throw error;\n }\n throw new Error(\n `Failed to extract digest from single-platform image ${imageRef}: ${error.message}`,\n );\n }\n}\n\n/**\n * Convert hex string to 32-byte array\n */\nfunction hexStringToBytes32(hexStr: string): Uint8Array {\n // Remove \"sha256:\" prefix if present\n let cleanHex = hexStr;\n if (hexStr.includes(\":\")) {\n cleanHex = hexStr.split(\":\")[1];\n }\n\n // Decode hex string\n const bytes = Buffer.from(cleanHex, \"hex\");\n\n if (bytes.length !== 32) {\n throw new Error(`Digest must be exactly 32 bytes, got ${bytes.length}`);\n }\n\n return new Uint8Array(bytes);\n}\n\n/**\n * Extract digest from repo digest string\n * Format: \"repo@sha256:xxxxx\" -> returns 32-byte digest\n */\nfunction extractDigestFromRepoDigest(repoDigest: string): Uint8Array {\n const prefix = \"@sha256:\";\n const idx = repoDigest.lastIndexOf(prefix);\n if (idx === -1) {\n throw new Error(`Invalid repo digest format: ${repoDigest}`);\n }\n\n const hexDigest = repoDigest.substring(idx + prefix.length);\n return hexStringToBytes32(hexDigest);\n}\n\n/**\n * Extract registry name from image reference\n * e.g., \"ghcr.io/user/repo:tag\" -> \"ghcr.io/user/repo\"\n */\nfunction extractRegistryName(imageRef: string): string {\n // Remove tag if present\n let name = imageRef;\n const tagIndex = name.lastIndexOf(\":\");\n if (tagIndex !== -1 && !name.substring(tagIndex + 1).includes(\"/\")) {\n name = name.substring(0, tagIndex);\n }\n\n // Remove digest if present\n const digestIndex = name.indexOf(\"@\");\n if (digestIndex !== -1) {\n name = name.substring(0, digestIndex);\n }\n\n // Prefix with docker.io/ if no registry is provided\n if ([...name].filter((c) => c === \"/\").length === 1) {\n name = `docker.io/${name}`;\n }\n\n // Default registry\n return name;\n}\n\n/**\n * Create platform error message\n */\nfunction createPlatformErrorMessage(imageRef: string, platforms: string[]): Error {\n const errorMsg = `ecloud requires linux/amd64 images for TEE deployment.\n\nImage: ${imageRef}\nFound platform(s): ${platforms.join(\", \")}\nRequired platform: ${DOCKER_PLATFORM}\n\nTo fix this issue:\n1. Manual fix:\n a. Rebuild your image with the correct platform:\n docker build --platform ${DOCKER_PLATFORM} -t ${imageRef} .\n b. Push the rebuilt image to your remote registry:\n docker push ${imageRef}\n\n2. Or use the SDK to build with the correct platform automatically.`;\n\n return new Error(errorMsg);\n}\n","/**\n * KMS encryption utilities\n * Implements RSA-OAEP-256 + AES-256-GCM encryption using JWE format\n */\n\nimport { Buffer } from \"buffer\";\nimport { importSPKI, CompactEncrypt, type CompactJWEHeaderParameters } from \"jose\";\n\n/**\n * Get app protected headers for encryption\n */\nexport function getAppProtectedHeaders(appID: string): Record<string, string> {\n return {\n \"x-eigenx-app-id\": appID,\n };\n}\n\n/**\n * Encrypt data using RSA-OAEP-256 for key encryption and AES-256-GCM for data encryption\n * Uses jose library which properly implements JWE with RSA-OAEP-256\n */\nexport async function encryptRSAOAEPAndAES256GCM(\n encryptionKeyPEM: string | Buffer,\n plaintext: Buffer,\n protectedHeaders?: Record<string, string> | null,\n): Promise<string> {\n const pemString =\n typeof encryptionKeyPEM === \"string\" ? encryptionKeyPEM : encryptionKeyPEM.toString(\"utf-8\");\n\n // Import RSA public key from PEM format\n // jose handles both PKIX and PKCS#1 formats automatically\n const publicKey = await importSPKI(pemString, \"RSA-OAEP-256\", {\n extractable: true,\n });\n\n // Build protected header\n const header: CompactJWEHeaderParameters = {\n alg: \"RSA-OAEP-256\", // Key encryption algorithm (SHA-256)\n enc: \"A256GCM\", // Content encryption algorithm\n ...(protectedHeaders || {}), // Add custom protected headers\n };\n\n // Encrypt using JWE compact serialization\n // CompactEncrypt is a class that builds and encrypts Compact JWE strings\n // Convert Buffer to Uint8Array for jose library\n const plaintextBytes = new Uint8Array(plaintext);\n const jwe = await new CompactEncrypt(plaintextBytes)\n .setProtectedHeader(header)\n .encrypt(publicKey);\n\n return jwe;\n}\n","/**\n * Environment file parsing and validation\n */\n\nimport * as fs from \"fs\";\nimport { ParsedEnvironment } from \"../types\";\n\nconst MNEMONIC_ENV_VAR = \"MNEMONIC\";\n\n/**\n * Parse environment file and split into public/private variables\n */\nexport function parseAndValidateEnvFile(envFilePath: string): ParsedEnvironment {\n if (!fs.existsSync(envFilePath)) {\n throw new Error(`Environment file not found: ${envFilePath}`);\n }\n\n const content = fs.readFileSync(envFilePath, \"utf-8\");\n const env: Record<string, string> = {};\n let mnemonicFiltered = false;\n\n // Parse .env file (simple parser - can be enhanced)\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n\n const equalIndex = trimmed.indexOf(\"=\");\n if (equalIndex === -1) {\n continue;\n }\n\n const key = trimmed.substring(0, equalIndex).trim();\n let value = trimmed.substring(equalIndex + 1).trim();\n\n // Remove quotes if present\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n // Filter out mnemonic\n if (key.toUpperCase() === MNEMONIC_ENV_VAR) {\n mnemonicFiltered = true;\n continue;\n }\n\n env[key] = value;\n }\n\n // Split into public and private\n const publicEnv: Record<string, string> = {};\n const privateEnv: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(env)) {\n if (key.endsWith(\"_PUBLIC\")) {\n publicEnv[key] = value;\n } else {\n privateEnv[key] = value;\n }\n }\n\n return {\n public: publicEnv,\n private: privateEnv,\n // Include mnemonicFiltered flag for logging\n _mnemonicFiltered: mnemonicFiltered,\n } as ParsedEnvironment & { _mnemonicFiltered?: boolean };\n}\n\n/**\n * Display environment variables for user confirmation\n */\nexport function displayEnvironmentVariables(\n parsed: ParsedEnvironment & { _mnemonicFiltered?: boolean },\n): void {\n console.log(\"\\nYour container will deploy with the following environment variables:\\n\");\n\n if (parsed._mnemonicFiltered) {\n console.log(\n \"\\x1b[3;36mMnemonic environment variable removed to be overridden by protocol provided mnemonic\\x1b[0m\\n\",\n );\n }\n\n // Print public variables\n if (Object.keys(parsed.public).length > 0) {\n console.log(\"PUBLIC VARIABLE\\tVALUE\");\n console.log(\"---------------\\t-----\");\n for (const [key, value] of Object.entries(parsed.public)) {\n console.log(`${key}\\t${value}`);\n }\n } else {\n console.log(\"No public variables found\");\n }\n\n console.log(\"\\n-----------------------------------------\\n\");\n\n // Print private variables\n if (Object.keys(parsed.private).length > 0) {\n console.log(\"PRIVATE VARIABLE\\tVALUE\");\n console.log(\"----------------\\t-----\\n\");\n for (const [key, value] of Object.entries(parsed.private)) {\n // Mask private values for display\n const masked =\n value.length > 8\n ? `${value.substring(0, 4)}...${value.substring(value.length - 4)}`\n : \"***\";\n console.log(`${key}\\t${masked}`);\n }\n } else {\n console.log(\"No private variables found\");\n }\n\n console.log();\n}\n","/**\n * Release preparation\n *\n * This module handles building/layering images, encrypting environment variables,\n * and creating the release struct.\n */\n\nimport { buildAndPushLayeredImage } from \"../docker/layer\";\nimport { layerRemoteImageIfNeeded } from \"../docker/layer\";\nimport { getImageDigestAndName } from \"../registry/digest\";\nimport { encryptRSAOAEPAndAES256GCM, getAppProtectedHeaders } from \"../encryption/kms\"; // getAppProtectedHeaders\nimport { getKMSKeysForEnvironment } from \"../utils/keys\";\nimport { REGISTRY_PROPAGATION_WAIT_SECONDS } from \"../constants\";\n\nimport { parseAndValidateEnvFile } from \"../env/parser\";\n\nimport { Release, EnvironmentConfig, Logger } from \"../types\";\n\nexport interface PrepareReleaseOptions {\n dockerfilePath?: string;\n imageRef: string;\n envFilePath?: string;\n logRedirect: string;\n resourceUsageAllow: string;\n instanceType: string;\n environmentConfig: EnvironmentConfig;\n appId: string;\n}\n\nexport interface PrepareReleaseResult {\n release: Release;\n finalImageRef: string;\n}\n\n/**\n * Prepare release from context\n */\nexport async function prepareRelease(\n options: PrepareReleaseOptions,\n logger: Logger,\n): Promise<PrepareReleaseResult> {\n const {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig,\n } = options;\n\n let finalImageRef = imageRef;\n\n // 1. Build/layer image if needed\n if (dockerfilePath) {\n // Build from Dockerfile\n logger.info(\"Building and pushing layered image...\");\n finalImageRef = await buildAndPushLayeredImage(\n {\n dockerfilePath,\n targetImageRef: imageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n\n // Wait for registry propagation\n logger.info(`Waiting ${REGISTRY_PROPAGATION_WAIT_SECONDS} seconds for registry propagation...`);\n await new Promise((resolve) => setTimeout(resolve, REGISTRY_PROPAGATION_WAIT_SECONDS * 1000));\n } else {\n // Layer remote image if needed\n logger.info(\"Checking if image needs layering...\");\n finalImageRef = await layerRemoteImageIfNeeded(\n {\n imageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n\n // Wait for registry propagation if image was layered\n if (finalImageRef !== imageRef) {\n logger.info(\n `Waiting ${REGISTRY_PROPAGATION_WAIT_SECONDS} seconds for registry propagation...`,\n );\n await new Promise((resolve) => setTimeout(resolve, REGISTRY_PROPAGATION_WAIT_SECONDS * 1000));\n }\n }\n\n // 2. Wait a moment for registry to process the push (especially for GHCR)\n logger.info(\"Waiting for registry to process image...\");\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n // 3. Get image digest and registry name\n logger.info(\"Extracting image digest...\");\n let digest: Uint8Array | undefined;\n let registry: string | undefined;\n\n // Retry getting digest in case registry needs more time\n let retries = 3;\n let lastError: Error | null = null;\n\n while (retries > 0) {\n try {\n const result = await getImageDigestAndName(finalImageRef);\n digest = result.digest;\n registry = result.registry;\n break;\n } catch (error: any) {\n lastError = error;\n retries--;\n if (retries > 0) {\n logger.info(`Digest extraction failed, retrying in 2 seconds... (${retries} retries left)`);\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n }\n }\n\n if (!digest || !registry) {\n throw new Error(\n `Failed to get image digest after retries. This usually means the image wasn't pushed successfully.\\n` +\n `Original error: ${lastError?.message}\\n` +\n `Please verify the image exists: docker manifest inspect ${finalImageRef}`,\n );\n }\n\n logger.info(`Image digest: ${Buffer.from(digest).toString(\"hex\")}`);\n logger.info(`Registry: ${registry}`);\n\n // 4. Parse and validate environment file\n let publicEnv: Record<string, string> = {};\n let privateEnv: Record<string, string> = {};\n\n if (envFilePath) {\n logger.info(\"Parsing environment file...\");\n const parsed = parseAndValidateEnvFile(envFilePath);\n publicEnv = parsed.public;\n privateEnv = parsed.private;\n } else {\n logger.info(\"Continuing without environment file\");\n }\n\n // 4. Add instance type to public env\n publicEnv[\"EIGEN_MACHINE_TYPE_PUBLIC\"] = instanceType;\n logger.info(`Instance type: ${instanceType}`);\n\n // 5. Encrypt private environment variables\n logger.info(\"Encrypting environment variables...\");\n const { encryptionKey } = getKMSKeysForEnvironment(\n environmentConfig.name,\n environmentConfig.build,\n );\n const protectedHeaders = getAppProtectedHeaders(options.appId);\n const privateEnvBytes = Buffer.from(JSON.stringify(privateEnv));\n const encryptedEnvStr = await encryptRSAOAEPAndAES256GCM(\n encryptionKey,\n privateEnvBytes,\n protectedHeaders,\n );\n\n // 6. Create release struct\n const release: Release = {\n rmsRelease: {\n artifacts: [\n {\n digest: new Uint8Array(digest),\n registry: registry,\n },\n ],\n upgradeByTime: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now\n },\n publicEnv: new Uint8Array(Buffer.from(JSON.stringify(publicEnv))),\n encryptedEnv: new Uint8Array(Buffer.from(encryptedEnvStr)),\n };\n\n return {\n release,\n finalImageRef,\n };\n}\n","/**\n * Contract interactions\n *\n * This module handles on-chain contract interactions using viem\n */\n\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { executeBatch, checkERC7702Delegation } from \"./eip7702\";\nimport {\n createWalletClient,\n createPublicClient,\n http,\n Address,\n Hex,\n encodeFunctionData,\n decodeErrorResult,\n} from \"viem\";\nimport type { WalletClient, PublicClient } from \"viem\";\nimport { hashAuthorization } from \"viem/utils\";\nimport { sign } from \"viem/accounts\";\n\nimport { addHexPrefix, getChainFromID } from \"../utils\";\n\nimport { EnvironmentConfig, Logger } from \"../types\";\nimport { Release } from \"../types\";\n\nimport AppControllerABI from \"../abis/AppController.json\";\nimport PermissionControllerABI from \"../abis/PermissionController.json\";\n\n/**\n * Gas estimation result\n */\nexport interface GasEstimate {\n /** Estimated gas limit for the transaction */\n gasLimit: bigint;\n /** Max fee per gas (EIP-1559) */\n maxFeePerGas: bigint;\n /** Max priority fee per gas (EIP-1559) */\n maxPriorityFeePerGas: bigint;\n /** Maximum cost in wei (gasLimit * maxFeePerGas) */\n maxCostWei: bigint;\n /** Maximum cost formatted as ETH string */\n maxCostEth: string;\n}\n\n/**\n * Options for estimating transaction gas\n */\nexport interface EstimateGasOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n to: Address;\n data: Hex;\n value?: bigint;\n}\n\n/**\n * Format Wei to ETH string\n */\nexport function formatETH(wei: bigint): string {\n const eth = Number(wei) / 1e18;\n const costStr = eth.toFixed(6);\n // Remove trailing zeros and decimal point if needed\n const trimmed = costStr.replace(/\\.?0+$/, \"\");\n // If result is \"0\", show \"<0.000001\" for small amounts\n if (trimmed === \"0\" && wei > 0n) {\n return \"<0.000001\";\n }\n return trimmed;\n}\n\n/**\n * Estimate gas cost for a transaction\n *\n * Use this to get cost estimate before prompting user for confirmation.\n */\nexport async function estimateTransactionGas(options: EstimateGasOptions): Promise<GasEstimate> {\n const { privateKey, rpcUrl, environmentConfig, to, data, value = 0n } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Get current gas prices\n const fees = await publicClient.estimateFeesPerGas();\n\n // Estimate gas for the transaction\n const gasLimit = await publicClient.estimateGas({\n account: account.address,\n to,\n data,\n value,\n });\n\n const maxFeePerGas = fees.maxFeePerGas;\n const maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n const maxCostWei = gasLimit * maxFeePerGas;\n const maxCostEth = formatETH(maxCostWei);\n\n return {\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n maxCostWei,\n maxCostEth,\n };\n}\n\nexport interface DeployAppOptions {\n privateKey: string; // Will be converted to Hex\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n salt: Uint8Array;\n release: Release;\n publicLogs: boolean;\n imageRef: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Prepared deploy batch ready for gas estimation and execution\n */\nexport interface PreparedDeployBatch {\n /** The app ID that will be deployed */\n appId: Address;\n /** The salt used for deployment */\n salt: Uint8Array;\n /** Batch executions to be sent */\n executions: Array<{ target: Address; value: bigint; callData: Hex }>;\n /** Wallet client for sending transaction */\n walletClient: WalletClient;\n /** Public client for reading chain state */\n publicClient: PublicClient;\n /** Environment configuration */\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Prepared upgrade batch ready for gas estimation and execution\n */\nexport interface PreparedUpgradeBatch {\n /** The app ID being upgraded */\n appId: Address;\n /** Batch executions to be sent */\n executions: Array<{ target: Address; value: bigint; callData: Hex }>;\n /** Wallet client for sending transaction */\n walletClient: WalletClient;\n /** Public client for reading chain state */\n publicClient: PublicClient;\n /** Environment configuration */\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Calculate app ID from owner address and salt\n */\nexport async function calculateAppID(\n privateKey: string | Hex,\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n salt: Uint8Array,\n): Promise<Address> {\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Ensure salt is properly formatted as hex string (32 bytes = 64 hex chars)\n const saltHexString = Buffer.from(salt).toString(\"hex\");\n // Pad to 64 characters if needed\n const paddedSaltHex = saltHexString.padStart(64, \"0\");\n const saltHex = `0x${paddedSaltHex}` as Hex;\n\n // Ensure address is a string (viem might return Hex type)\n const accountAddress =\n typeof account.address === \"string\" ? account.address : (account.address as Buffer).toString();\n\n const appID = await publicClient.readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"calculateAppId\",\n args: [accountAddress as Address, saltHex],\n });\n\n return appID as Address;\n}\n\n/**\n * Options for preparing a deploy batch\n */\nexport interface PrepareDeployBatchOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n salt: Uint8Array;\n release: Release;\n publicLogs: boolean;\n}\n\n/**\n * Prepare deploy batch - creates executions without sending transaction\n *\n * Use this to get the prepared batch for gas estimation before executing.\n */\nexport async function prepareDeployBatch(\n options: PrepareDeployBatchOptions,\n logger: Logger,\n): Promise<PreparedDeployBatch> {\n const { privateKey, rpcUrl, environmentConfig, salt, release, publicLogs } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // 1. Calculate app ID\n logger.info(\"Calculating app ID...\");\n const appId = await calculateAppID(privateKeyHex, rpcUrl, environmentConfig, salt);\n logger.info(`App ID: ${appId}`);\n\n // Verify the app ID calculation matches what createApp will deploy\n logger.debug(`App ID calculated: ${appId}`);\n logger.debug(`This address will be used for acceptAdmin call`);\n\n // 2. Pack create app call\n const saltHexString = Buffer.from(salt).toString(\"hex\");\n const paddedSaltHex = saltHexString.padStart(64, \"0\");\n const saltHex = `0x${paddedSaltHex}` as Hex;\n\n // Convert Release Uint8Array values to hex strings for viem\n const releaseForViem = {\n rmsRelease: {\n artifacts: release.rmsRelease.artifacts.map((artifact) => ({\n digest: `0x${Buffer.from(artifact.digest).toString(\"hex\").padStart(64, \"0\")}` as Hex,\n registry: artifact.registry,\n })),\n upgradeByTime: release.rmsRelease.upgradeByTime,\n },\n publicEnv: `0x${Buffer.from(release.publicEnv).toString(\"hex\")}` as Hex,\n encryptedEnv: `0x${Buffer.from(release.encryptedEnv).toString(\"hex\")}` as Hex,\n };\n\n const createData = encodeFunctionData({\n abi: AppControllerABI,\n functionName: \"createApp\",\n args: [saltHex, releaseForViem],\n });\n\n // 3. Pack accept admin call\n const acceptAdminData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"acceptAdmin\",\n args: [appId],\n });\n\n // 4. Assemble executions\n // CRITICAL: Order matters! createApp must complete first\n const executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }> = [\n {\n target: environmentConfig.appControllerAddress as Address,\n value: 0n,\n callData: createData,\n },\n {\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: acceptAdminData,\n },\n ];\n\n // 5. Add public logs permission if requested\n if (publicLogs) {\n const anyoneCanViewLogsData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"setAppointee\",\n args: [\n appId,\n \"0x493219d9949348178af1f58740655951a8cd110c\" as Address, // AnyoneCanCallAddress\n \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address, // ApiPermissionsTarget\n \"0x2fd3f2fe\" as Hex, // CanViewAppLogsPermission\n ],\n });\n executions.push({\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: anyoneCanViewLogsData,\n });\n }\n\n return {\n appId,\n salt,\n executions,\n walletClient,\n publicClient,\n environmentConfig,\n };\n}\n\n/**\n * Execute a prepared deploy batch\n */\nexport async function executeDeployBatch(\n prepared: PreparedDeployBatch,\n gas: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint } | undefined,\n logger: Logger,\n): Promise<{ appId: Address; txHash: Hex }> {\n const pendingMessage = \"Deploying new app...\";\n\n const txHash = await executeBatch(\n {\n walletClient: prepared.walletClient,\n publicClient: prepared.publicClient,\n environmentConfig: prepared.environmentConfig,\n executions: prepared.executions,\n pendingMessage,\n gas,\n },\n logger,\n );\n\n return { appId: prepared.appId, txHash };\n}\n\n/**\n * Deploy app on-chain (convenience wrapper that prepares and executes)\n */\nexport async function deployApp(\n options: DeployAppOptions,\n logger: Logger,\n): Promise<{ appId: Address; txHash: Hex }> {\n const prepared = await prepareDeployBatch(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environmentConfig: options.environmentConfig,\n salt: options.salt,\n release: options.release,\n publicLogs: options.publicLogs,\n },\n logger,\n );\n\n return executeDeployBatch(prepared, options.gas, logger);\n}\n\nexport interface UpgradeAppOptions {\n privateKey: string; // Will be converted to Hex\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n release: Release;\n publicLogs: boolean;\n needsPermissionChange: boolean;\n imageRef: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Options for preparing an upgrade batch\n */\nexport interface PrepareUpgradeBatchOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n release: Release;\n publicLogs: boolean;\n needsPermissionChange: boolean;\n}\n\n/**\n * Prepare upgrade batch - creates executions without sending transaction\n *\n * Use this to get the prepared batch for gas estimation before executing.\n */\nexport async function prepareUpgradeBatch(\n options: PrepareUpgradeBatchOptions,\n): Promise<PreparedUpgradeBatch> {\n const {\n privateKey,\n rpcUrl,\n environmentConfig,\n appId,\n release,\n publicLogs,\n needsPermissionChange,\n } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // 1. Pack upgrade app call\n // Convert Release Uint8Array values to hex strings for viem\n const releaseForViem = {\n rmsRelease: {\n artifacts: release.rmsRelease.artifacts.map((artifact) => ({\n digest: `0x${Buffer.from(artifact.digest).toString(\"hex\").padStart(64, \"0\")}` as Hex,\n registry: artifact.registry,\n })),\n upgradeByTime: release.rmsRelease.upgradeByTime,\n },\n publicEnv: `0x${Buffer.from(release.publicEnv).toString(\"hex\")}` as Hex,\n encryptedEnv: `0x${Buffer.from(release.encryptedEnv).toString(\"hex\")}` as Hex,\n };\n\n const upgradeData = encodeFunctionData({\n abi: AppControllerABI,\n functionName: \"upgradeApp\",\n args: [appId, releaseForViem],\n });\n\n // 2. Start with upgrade execution\n const executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }> = [\n {\n target: environmentConfig.appControllerAddress as Address,\n value: 0n,\n callData: upgradeData,\n },\n ];\n\n // 3. Add permission transaction if needed\n if (needsPermissionChange) {\n if (publicLogs) {\n // Add public permission (private→public)\n const addLogsData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"setAppointee\",\n args: [\n appId,\n \"0x493219d9949348178af1f58740655951a8cd110c\" as Address, // AnyoneCanCallAddress\n \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address, // ApiPermissionsTarget\n \"0x2fd3f2fe\" as Hex, // CanViewAppLogsPermission\n ],\n });\n executions.push({\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: addLogsData,\n });\n } else {\n // Remove public permission (public→private)\n const removeLogsData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"removeAppointee\",\n args: [\n appId,\n \"0x493219d9949348178af1f58740655951a8cd110c\" as Address, // AnyoneCanCallAddress\n \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address, // ApiPermissionsTarget\n \"0x2fd3f2fe\" as Hex, // CanViewAppLogsPermission\n ],\n });\n executions.push({\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: removeLogsData,\n });\n }\n }\n\n return {\n appId,\n executions,\n walletClient,\n publicClient,\n environmentConfig,\n };\n}\n\n/**\n * Execute a prepared upgrade batch\n */\nexport async function executeUpgradeBatch(\n prepared: PreparedUpgradeBatch,\n gas: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint } | undefined,\n logger: Logger,\n): Promise<Hex> {\n const pendingMessage = `Upgrading app ${prepared.appId}...`;\n\n const txHash = await executeBatch(\n {\n walletClient: prepared.walletClient,\n publicClient: prepared.publicClient,\n environmentConfig: prepared.environmentConfig,\n executions: prepared.executions,\n pendingMessage,\n gas,\n },\n logger,\n );\n\n return txHash;\n}\n\n/**\n * Upgrade app on-chain (convenience wrapper that prepares and executes)\n */\nexport async function upgradeApp(options: UpgradeAppOptions, logger: Logger): Promise<Hex> {\n const prepared = await prepareUpgradeBatch({\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environmentConfig: options.environmentConfig,\n appId: options.appId,\n release: options.release,\n publicLogs: options.publicLogs,\n needsPermissionChange: options.needsPermissionChange,\n });\n\n return executeUpgradeBatch(prepared, options.gas, logger);\n}\n\n/**\n * Send and wait for transaction with confirmation support\n */\nexport interface SendTransactionOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n to: Address;\n data: Hex;\n value?: bigint;\n pendingMessage: string;\n txDescription: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\nexport async function sendAndWaitForTransaction(\n options: SendTransactionOptions,\n logger: Logger,\n): Promise<Hex> {\n const {\n privateKey,\n rpcUrl,\n environmentConfig,\n to,\n data,\n value = 0n,\n pendingMessage,\n txDescription,\n gas,\n } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // Show pending message if provided\n if (pendingMessage) {\n logger.info(`\\n${pendingMessage}`);\n }\n\n // Send transaction with optional gas params\n const hash = await walletClient.sendTransaction({\n account,\n to,\n data,\n value,\n ...(gas?.maxFeePerGas && { maxFeePerGas: gas.maxFeePerGas }),\n ...(gas?.maxPriorityFeePerGas && { maxPriorityFeePerGas: gas.maxPriorityFeePerGas }),\n });\n\n logger.info(`Transaction sent: ${hash}`);\n\n // Wait for receipt\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status === \"reverted\") {\n let revertReason = \"Unknown reason\";\n try {\n await publicClient.call({\n to,\n data,\n account: account.address,\n });\n } catch (callError: any) {\n if (callError.data) {\n try {\n const decoded = decodeErrorResult({\n abi: AppControllerABI,\n data: callError.data,\n });\n const formattedError = formatAppControllerError(decoded);\n revertReason = formattedError.message;\n } catch {\n revertReason = callError.message || \"Unknown reason\";\n }\n } else {\n revertReason = callError.message || \"Unknown reason\";\n }\n }\n logger.error(`${txDescription} transaction (hash: ${hash}) reverted: ${revertReason}`);\n throw new Error(`${txDescription} transaction (hash: ${hash}) reverted: ${revertReason}`);\n }\n\n return hash;\n}\n\n/**\n * Format AppController errors to user-friendly messages\n */\nfunction formatAppControllerError(decoded: {\n errorName: string;\n args?: readonly unknown[];\n}): Error {\n const errorName = decoded.errorName;\n\n switch (errorName) {\n case \"MaxActiveAppsExceeded\":\n return new Error(\n \"you have reached your app deployment limit. To request access or increase your limit, please visit https://onboarding.eigencloud.xyz/ or reach out to the Eigen team\",\n );\n case \"GlobalMaxActiveAppsExceeded\":\n return new Error(\n \"the platform has reached the maximum number of active apps. please try again later\",\n );\n case \"InvalidPermissions\":\n return new Error(\"you don't have permission to perform this operation\");\n case \"AppAlreadyExists\":\n return new Error(\"an app with this owner and salt already exists\");\n case \"AppDoesNotExist\":\n return new Error(\"the specified app does not exist\");\n case \"InvalidAppStatus\":\n return new Error(\"the app is in an invalid state for this operation\");\n case \"MoreThanOneArtifact\":\n return new Error(\"only one artifact is allowed per release\");\n case \"InvalidSignature\":\n return new Error(\"invalid signature provided\");\n case \"SignatureExpired\":\n return new Error(\"the provided signature has expired\");\n case \"InvalidReleaseMetadataURI\":\n return new Error(\"invalid release metadata URI provided\");\n case \"InvalidShortString\":\n return new Error(\"invalid short string format\");\n default:\n return new Error(`contract error: ${errorName}`);\n }\n}\n\n/**\n * Get active app count for a user\n */\nexport async function getActiveAppCount(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n user: Address,\n): Promise<number> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const count = await publicClient.readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"getActiveAppCount\",\n args: [user],\n });\n\n return Number(count);\n}\n\n/**\n * Get max active apps per user (quota limit)\n */\nexport async function getMaxActiveAppsPerUser(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n user: Address,\n): Promise<number> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const quota = await publicClient.readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"getMaxActiveAppsPerUser\",\n args: [user],\n });\n\n return Number(quota);\n}\n\n/**\n * Get apps by creator (paginated)\n */\nexport interface AppConfig {\n release: any; // Release struct from contract\n status: number; // AppStatus enum\n}\n\nexport async function getAppsByCreator(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n creator: Address,\n offset: bigint,\n limit: bigint,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const result = (await publicClient.readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"getAppsByCreator\",\n args: [creator, offset, limit],\n })) as [Address[], AppConfig[]];\n\n // Result is a tuple: [Address[], AppConfig[]]\n return {\n apps: result[0],\n appConfigs: result[1],\n };\n}\n\n/**\n * Get apps by developer\n */\nexport async function getAppsByDeveloper(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n developer: Address,\n offset: bigint,\n limit: bigint,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const result = (await publicClient.readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"getAppsByDeveloper\",\n args: [developer, offset, limit],\n })) as [Address[], AppConfig[]];\n\n // Result is a tuple: [Address[], AppConfig[]]\n return {\n apps: result[0],\n appConfigs: result[1],\n };\n}\n\n/**\n * Fetch all apps by a developer by auto-pagination\n */\nexport async function getAllAppsByDeveloper(\n rpcUrl: string,\n env: EnvironmentConfig,\n developer: Address,\n pageSize: bigint = 100n,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\n let offset = 0n;\n const allApps: Address[] = [];\n const allConfigs: AppConfig[] = [];\n\n while (true) {\n const { apps, appConfigs } = await getAppsByDeveloper(rpcUrl, env, developer, offset, pageSize);\n\n if (apps.length === 0) break;\n\n allApps.push(...apps);\n allConfigs.push(...appConfigs);\n\n if (apps.length < Number(pageSize)) break;\n\n offset += pageSize;\n }\n\n return {\n apps: allApps,\n appConfigs: allConfigs,\n };\n}\n\n/**\n * Get latest release block numbers for multiple apps\n */\nexport async function getAppLatestReleaseBlockNumbers(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n appIDs: Address[],\n): Promise<Map<Address, number>> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Fetch block numbers in parallel\n const results = await Promise.all(\n appIDs.map((appID) =>\n publicClient\n .readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"getAppLatestReleaseBlockNumber\",\n args: [appID],\n })\n .catch(() => null),\n ),\n );\n\n const blockNumbers = new Map<Address, number>();\n for (let i = 0; i < appIDs.length; i++) {\n const result = results[i];\n if (result !== null && result !== undefined) {\n blockNumbers.set(appIDs[i], Number(result));\n }\n }\n\n return blockNumbers;\n}\n\n/**\n * Get block timestamps for multiple block numbers\n */\nexport async function getBlockTimestamps(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n blockNumbers: number[],\n): Promise<Map<number, number>> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Deduplicate block numbers\n const uniqueBlockNumbers = [...new Set(blockNumbers)].filter((n) => n > 0);\n\n const timestamps = new Map<number, number>();\n\n // Fetch blocks in parallel\n const blocks = await Promise.all(\n uniqueBlockNumbers.map((blockNumber) =>\n publicClient.getBlock({ blockNumber: BigInt(blockNumber) }).catch(() => null),\n ),\n );\n\n for (let i = 0; i < uniqueBlockNumbers.length; i++) {\n const block = blocks[i];\n if (block) {\n timestamps.set(uniqueBlockNumbers[i], Number(block.timestamp));\n }\n }\n\n return timestamps;\n}\n\n/**\n * Suspend apps for an account\n */\nexport async function suspend(\n options: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n account: Address;\n apps: Address[];\n },\n logger: Logger,\n): Promise<Hex | false> {\n const { privateKey, rpcUrl, environmentConfig, account, apps } = options;\n\n const suspendData = encodeFunctionData({\n abi: AppControllerABI,\n functionName: \"suspend\",\n args: [account, apps],\n });\n\n const pendingMessage = `Suspending ${apps.length} app(s)...`;\n\n return sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl,\n environmentConfig,\n to: environmentConfig.appControllerAddress as Address,\n data: suspendData,\n pendingMessage,\n txDescription: \"Suspend\",\n },\n logger,\n );\n}\n\n/**\n * Check if account is delegated to the ERC-7702 delegator\n */\nexport async function isDelegated(options: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n}): Promise<boolean> {\n const { privateKey, rpcUrl, environmentConfig } = options;\n\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n return checkERC7702Delegation(\n publicClient,\n account.address,\n environmentConfig.erc7702DelegatorAddress as Address,\n );\n}\n\n/**\n * Undelegate account (removes EIP-7702 delegation)\n */\nexport async function undelegate(\n options: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n },\n logger: Logger,\n): Promise<Hex> {\n const { privateKey, rpcUrl, environmentConfig } = options;\n\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // Create authorization to undelegate (empty address = undelegate)\n const transactionNonce = await publicClient.getTransactionCount({\n address: account.address,\n blockTag: \"pending\",\n });\n\n const chainId = await publicClient.getChainId();\n const authorizationNonce = BigInt(transactionNonce) + 1n;\n\n const authorization = {\n chainId: Number(chainId),\n address: \"0x0000000000000000000000000000000000000000\" as Address, // Empty address = undelegate\n nonce: authorizationNonce,\n };\n\n const sighash = hashAuthorization({\n chainId: authorization.chainId,\n contractAddress: authorization.address,\n nonce: Number(authorization.nonce),\n });\n\n const sig = await sign({\n hash: sighash,\n privateKey: privateKeyHex,\n });\n\n const v = Number(sig.v);\n const yParity = v === 27 ? 0 : 1;\n\n const authorizationList = [\n {\n chainId: authorization.chainId,\n address: authorization.address,\n nonce: Number(authorization.nonce),\n r: sig.r as Hex,\n s: sig.s as Hex,\n yParity,\n },\n ];\n\n // Send transaction with authorization list\n const hash = await walletClient.sendTransaction({\n account,\n to: account.address, // Send to self\n data: \"0x\" as Hex, // Empty data\n value: 0n,\n authorizationList,\n });\n\n logger.info(`Transaction sent: ${hash}`);\n\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status === \"reverted\") {\n logger.error(`Undelegate transaction (hash: ${hash}) reverted`);\n throw new Error(`Undelegate transaction (hash: ${hash}) reverted`);\n }\n\n return hash;\n}\n","/**\n * EIP-7702 transaction handling\n *\n * This module handles EIP-7702 delegation and batch execution\n */\n\nimport {\n Address,\n Hex,\n encodeFunctionData,\n encodeAbiParameters,\n decodeErrorResult,\n keccak256,\n toBytes,\n concat,\n} from \"viem\";\n\nimport type { WalletClient, PublicClient, SendTransactionParameters } from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\n\nimport ERC7702DelegatorABI from \"../abis/ERC7702Delegator.json\";\n\nimport { GasEstimate, formatETH } from \"./caller\";\n\n/**\n * Options for estimating batch gas\n */\nexport interface EstimateBatchGasOptions {\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }>;\n}\n\n/**\n * Estimate gas cost for a batch transaction\n *\n * Use this to get cost estimate before prompting user for confirmation.\n * Note: This provides a conservative estimate since batch transactions\n * through EIP-7702 can have variable costs.\n */\nexport async function estimateBatchGas(options: EstimateBatchGasOptions): Promise<GasEstimate> {\n const { publicClient, executions } = options;\n\n // Get current gas prices\n const fees = await publicClient.estimateFeesPerGas();\n\n // For batch operations, we use a conservative estimate\n // Each execution adds ~50k gas, plus base cost of ~100k for the delegator call\n const baseGas = 100000n;\n const perExecutionGas = 50000n;\n const estimatedGas = baseGas + BigInt(executions.length) * perExecutionGas;\n\n // Add 20% buffer for safety\n const gasLimit = (estimatedGas * 120n) / 100n;\n\n const maxFeePerGas = fees.maxFeePerGas;\n const maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n const maxCostWei = gasLimit * maxFeePerGas;\n const maxCostEth = formatETH(maxCostWei);\n\n return {\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n maxCostWei,\n maxCostEth,\n };\n}\n\nexport interface ExecuteBatchOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }>;\n pendingMessage: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Check if account is delegated to ERC-7702 delegator\n */\nexport async function checkERC7702Delegation(\n publicClient: PublicClient,\n account: Address,\n delegatorAddress: Address,\n): Promise<boolean> {\n const code = await publicClient.getBytecode({ address: account });\n if (!code) {\n return false;\n }\n\n // Check if code matches EIP-7702 delegation pattern: 0xef0100 || delegator_address\n const expectedCode = `0xef0100${delegatorAddress.slice(2)}`;\n return code.toLowerCase() === expectedCode.toLowerCase();\n}\n\n/**\n * Execute batch of operations via EIP-7702 delegator\n *\n * This function uses viem's built-in EIP-7702 support to handle transaction\n * construction, signing, and sending. We focus on:\n * 1. Encoding the executions correctly\n * 2. Creating authorization if needed\n * 3. Passing the right parameters to viem\n */\nexport async function executeBatch(options: ExecuteBatchOptions, logger: Logger): Promise<Hex> {\n const { walletClient, publicClient, environmentConfig, executions, pendingMessage, gas } =\n options;\n\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"Wallet client must have an account\");\n }\n\n const chain = walletClient.chain;\n if (!chain) {\n throw new Error(\"Wallet client must have a chain\");\n }\n\n // 1. Encode executions array\n // The Execution struct is: { target: address, value: uint256, callData: bytes }\n // Go's EncodeExecutions uses abi.Arguments.Pack which produces standard ABI encoding\n const encodedExecutions = encodeAbiParameters(\n [\n {\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"callData\", type: \"bytes\" },\n ],\n },\n ],\n [executions],\n );\n\n // 2. Pack ExecuteBatch call\n // Mode 0x01 is executeBatchMode (32 bytes, padded) (big endian)\n const executeBatchMode =\n \"0x0100000000000000000000000000000000000000000000000000000000000000\" as Hex;\n\n // Encode the execute function call\n // Function signature: execute(bytes32 _mode, bytes _executionCalldata)\n // Function selector: 0xe9ae5c53\n let executeBatchData: Hex;\n try {\n executeBatchData = encodeFunctionData({\n abi: ERC7702DelegatorABI,\n functionName: \"execute\",\n args: [executeBatchMode, encodedExecutions],\n });\n } catch {\n // Fallback: Manually construct if viem selects wrong overload\n const functionSignature = \"execute(bytes32,bytes)\";\n const selector = keccak256(toBytes(functionSignature)).slice(0, 10) as Hex;\n const encodedParams = encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"bytes\" }],\n [executeBatchMode, encodedExecutions],\n );\n executeBatchData = concat([selector as Hex, encodedParams]) as Hex;\n }\n\n // 3. Check if account is delegated\n const isDelegated = await checkERC7702Delegation(\n publicClient,\n account.address,\n environmentConfig.erc7702DelegatorAddress as Address,\n );\n\n // 4. Create authorization if needed\n let authorizationList: Awaited<ReturnType<typeof walletClient.signAuthorization>>[] = [];\n\n if (!isDelegated) {\n const transactionNonce = await publicClient.getTransactionCount({\n address: account.address,\n blockTag: \"pending\",\n });\n\n const chainId = await publicClient.getChainId();\n const authorizationNonce = transactionNonce + 1;\n\n const signedAuthorization = await walletClient.signAuthorization({\n account,\n contractAddress: environmentConfig.erc7702DelegatorAddress as Address,\n chainId: Number(chainId),\n nonce: authorizationNonce,\n });\n\n authorizationList = [signedAuthorization];\n }\n\n // 5. Show pending message\n if (pendingMessage) {\n logger.info(pendingMessage);\n }\n\n const txRequest: SendTransactionParameters = {\n account: walletClient.account!,\n chain,\n to: account.address,\n data: executeBatchData,\n value: 0n,\n };\n\n if (authorizationList.length > 0) {\n txRequest.authorizationList = authorizationList;\n }\n\n // Add gas params if provided\n if (gas?.maxFeePerGas) {\n txRequest.maxFeePerGas = gas.maxFeePerGas;\n }\n if (gas?.maxPriorityFeePerGas) {\n txRequest.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;\n }\n\n const hash = await walletClient.sendTransaction(txRequest);\n logger.info(`Transaction sent: ${hash}`);\n\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status === \"reverted\") {\n let revertReason = \"Unknown reason\";\n try {\n await publicClient.call({\n to: account.address,\n data: executeBatchData,\n account: account.address,\n });\n } catch (callError: any) {\n if (callError.data) {\n try {\n const decoded = decodeErrorResult({\n abi: ERC7702DelegatorABI,\n data: callError.data,\n });\n revertReason = `${decoded.errorName}: ${JSON.stringify(decoded.args)}`;\n } catch {\n revertReason = callError.message || \"Unknown reason\";\n }\n } else {\n revertReason = callError.message || \"Unknown reason\";\n }\n }\n throw new Error(`Transaction reverted: ${hash}. Reason: ${revertReason}`);\n }\n\n return hash;\n}\n","[\n {\n \"type\": \"constructor\",\n \"inputs\": [\n {\n \"name\": \"_delegationManager\",\n \"type\": \"address\",\n \"internalType\": \"contractIDelegationManager\"\n },\n {\n \"name\": \"_entryPoint\",\n \"type\": \"address\",\n \"internalType\": \"contractIEntryPoint\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"receive\",\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"DOMAIN_VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"NAME\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"PACKED_USER_OP_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addDeposit\",\n \"inputs\": [],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"delegationManager\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIDelegationManager\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"disableDelegation\",\n \"inputs\": [\n {\n \"name\": \"_delegation\",\n \"type\": \"tuple\",\n \"internalType\": \"structDelegation\",\n \"components\": [\n {\n \"name\": \"delegate\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"delegator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"authority\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"caveats\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structCaveat[]\",\n \"components\": [\n {\n \"name\": \"enforcer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"terms\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"args\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n },\n {\n \"name\": \"salt\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"eip712Domain\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"fields\",\n \"type\": \"bytes1\",\n \"internalType\": \"bytes1\"\n },\n {\n \"name\": \"name\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n },\n {\n \"name\": \"version\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n },\n {\n \"name\": \"chainId\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"verifyingContract\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"salt\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"extensions\",\n \"type\": \"uint256[]\",\n \"internalType\": \"uint256[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"enableDelegation\",\n \"inputs\": [\n {\n \"name\": \"_delegation\",\n \"type\": \"tuple\",\n \"internalType\": \"structDelegation\",\n \"components\": [\n {\n \"name\": \"delegate\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"delegator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"authority\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"caveats\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structCaveat[]\",\n \"components\": [\n {\n \"name\": \"enforcer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"terms\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"args\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n },\n {\n \"name\": \"salt\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"entryPoint\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIEntryPoint\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"execute\",\n \"inputs\": [\n {\n \"name\": \"_execution\",\n \"type\": \"tuple\",\n \"internalType\": \"structExecution\",\n \"components\": [\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"value\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"execute\",\n \"inputs\": [\n {\n \"name\": \"_mode\",\n \"type\": \"bytes32\",\n \"internalType\": \"ModeCode\"\n },\n {\n \"name\": \"_executionCalldata\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"executeFromExecutor\",\n \"inputs\": [\n {\n \"name\": \"_mode\",\n \"type\": \"bytes32\",\n \"internalType\": \"ModeCode\"\n },\n {\n \"name\": \"_executionCalldata\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"returnData_\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n }\n ],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getDeposit\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getDomainHash\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getNonce\",\n \"inputs\": [\n {\n \"name\": \"_key\",\n \"type\": \"uint192\",\n \"internalType\": \"uint192\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getNonce\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPackedUserOperationHash\",\n \"inputs\": [\n {\n \"name\": \"_userOp\",\n \"type\": \"tuple\",\n \"internalType\": \"structPackedUserOperation\",\n \"components\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"initCode\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"accountGasLimits\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"preVerificationGas\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"gasFees\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"paymasterAndData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPackedUserOperationTypedDataHash\",\n \"inputs\": [\n {\n \"name\": \"_userOp\",\n \"type\": \"tuple\",\n \"internalType\": \"structPackedUserOperation\",\n \"components\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"initCode\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"accountGasLimits\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"preVerificationGas\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"gasFees\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"paymasterAndData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isDelegationDisabled\",\n \"inputs\": [\n {\n \"name\": \"_delegationHash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isValidSignature\",\n \"inputs\": [\n {\n \"name\": \"_hash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"_signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"magicValue_\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"onERC1155BatchReceived\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256[]\",\n \"internalType\": \"uint256[]\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256[]\",\n \"internalType\": \"uint256[]\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"onERC1155Received\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"onERC721Received\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"redeemDelegations\",\n \"inputs\": [\n {\n \"name\": \"_permissionContexts\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n },\n {\n \"name\": \"_modes\",\n \"type\": \"bytes32[]\",\n \"internalType\": \"ModeCode[]\"\n },\n {\n \"name\": \"_executionCallDatas\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"supportsExecutionMode\",\n \"inputs\": [\n {\n \"name\": \"_mode\",\n \"type\": \"bytes32\",\n \"internalType\": \"ModeCode\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"supportsInterface\",\n \"inputs\": [\n {\n \"name\": \"_interfaceId\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"validateUserOp\",\n \"inputs\": [\n {\n \"name\": \"_userOp\",\n \"type\": \"tuple\",\n \"internalType\": \"structPackedUserOperation\",\n \"components\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"initCode\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"accountGasLimits\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"preVerificationGas\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"gasFees\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"paymasterAndData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n },\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"_missingAccountFunds\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"validationData_\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"withdrawDeposit\",\n \"inputs\": [\n {\n \"name\": \"_withdrawAddress\",\n \"type\": \"address\",\n \"internalType\": \"addresspayable\"\n },\n {\n \"name\": \"_withdrawAmount\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"event\",\n \"name\": \"EIP712DomainChanged\",\n \"inputs\": [],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"SentPrefund\",\n \"inputs\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"amount\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"success\",\n \"type\": \"bool\",\n \"indexed\": false,\n \"internalType\": \"bool\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"SetDelegationManager\",\n \"inputs\": [\n {\n \"name\": \"newDelegationManager\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIDelegationManager\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"SetEntryPoint\",\n \"inputs\": [\n {\n \"name\": \"entryPoint\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIEntryPoint\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"TryExecuteUnsuccessful\",\n \"inputs\": [\n {\n \"name\": \"batchExecutionindex\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"result\",\n \"type\": \"bytes\",\n \"indexed\": false,\n \"internalType\": \"bytes\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"ECDSAInvalidSignature\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"ECDSAInvalidSignatureLength\",\n \"inputs\": [\n {\n \"name\": \"length\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"ECDSAInvalidSignatureS\",\n \"inputs\": [\n {\n \"name\": \"s\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"ExecutionFailed\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidEIP712NameLength\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidEIP712VersionLength\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidShortString\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotDelegationManager\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotEntryPoint\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotEntryPointOrSelf\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotSelf\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"StringTooLong\",\n \"inputs\": [\n {\n \"name\": \"str\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"UnauthorizedCallContext\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"UnsupportedCallType\",\n \"inputs\": [\n {\n \"name\": \"callType\",\n \"type\": \"bytes1\",\n \"internalType\": \"CallType\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"UnsupportedExecType\",\n \"inputs\": [\n {\n \"name\": \"execType\",\n \"type\": \"bytes1\",\n \"internalType\": \"ExecType\"\n }\n ]\n }\n]\n","/**\n * Default logger\n */\n\nimport { Logger } from \"../types\";\n\nexport const defaultLogger: Logger = {\n info: (...args) => console.info(...args),\n warn: (...args) => console.warn(...args),\n error: (...args) => console.error(...args),\n debug: (...args) => console.debug(...args),\n};\n\nexport const getLogger: (verbose?: boolean) => Logger = (verbose?: boolean) => ({\n info: (...args) => console.info(...args),\n warn: (...args) => console.warn(...args),\n error: (...args) => console.error(...args),\n debug: (...args) => verbose && console.debug(...args),\n});\n","/**\n * UserAPI Client to manage interactions with the coordinator\n */\n\nimport axios, { AxiosResponse } from \"axios\";\nimport FormData from \"form-data\";\nimport { Address, Hex, createPublicClient, http } from \"viem\";\nimport { calculatePermissionSignature } from \"./auth\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { EnvironmentConfig } from \"../types\";\nimport { addHexPrefix, stripHexPrefix, getChainFromID } from \"./helpers\";\n\nexport interface AppProfileInfo {\n name: string;\n website?: string;\n description?: string;\n xURL?: string;\n imageURL?: string;\n}\n\nexport interface AppMetrics {\n cpu_utilization_percent?: number;\n memory_utilization_percent?: number;\n memory_used_bytes?: number;\n memory_total_bytes?: number;\n}\n\nexport interface DerivedAddress {\n address: string;\n derivationPath: string;\n}\n\nexport interface AppInfo {\n address: Address;\n status: string;\n ip: string;\n machineType: string;\n profile?: AppProfileInfo;\n metrics?: AppMetrics;\n evmAddresses: DerivedAddress[];\n solanaAddresses: DerivedAddress[];\n}\n\nexport interface AppInfoResponse {\n apps: Array<{\n addresses: {\n data: {\n evmAddresses: DerivedAddress[];\n solanaAddresses: DerivedAddress[];\n };\n signature: string;\n };\n app_status: string;\n ip: string;\n machine_type: string;\n profile?: AppProfileInfo;\n metrics?: AppMetrics;\n }>;\n}\n\nconst MAX_ADDRESS_COUNT = 5;\n\n// Permission constants\nexport const CanViewAppLogsPermission = \"0x2fd3f2fe\" as Hex;\nexport const CanViewSensitiveAppInfoPermission = \"0x0e67b22f\" as Hex;\nexport const CanUpdateAppProfilePermission = \"0x036fef61\" as Hex;\n\n/**\n * SDK_VERSION_BUILD_TIME is replaced at build time by tsup's define option\n */\n// @ts-ignore - SDK_VERSION_BUILD_TIME is injected at build time by tsup\ndeclare const SDK_VERSION_BUILD_TIME: string | undefined;\n\n/**\n * Get the default client ID using the build-time version\n */\nfunction getDefaultClientId(): string {\n // @ts-ignore - SDK_VERSION_BUILD_TIME is injected at build time\n const version = typeof SDK_VERSION_BUILD_TIME !== \"undefined\" ? SDK_VERSION_BUILD_TIME : \"0.0.0\";\n return `ecloud-sdk/v${version}`;\n}\n\nexport class UserApiClient {\n private readonly account?: ReturnType<typeof privateKeyToAccount>;\n private readonly rpcUrl?: string;\n private readonly clientId: string;\n\n constructor(\n private readonly config: EnvironmentConfig,\n privateKey?: string | Hex,\n rpcUrl?: string,\n clientId?: string,\n ) {\n if (privateKey) {\n const privateKeyHex = addHexPrefix(privateKey);\n this.account = privateKeyToAccount(privateKeyHex);\n }\n this.rpcUrl = rpcUrl;\n this.clientId = clientId || getDefaultClientId();\n }\n\n async getInfos(appIDs: Address[], addressCount = 1): Promise<AppInfo[]> {\n const count = Math.min(addressCount, MAX_ADDRESS_COUNT);\n\n const endpoint = `${this.config.userApiServerURL}/info`;\n const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(\",\") })}`;\n\n const res = await this.makeAuthenticatedRequest(url, CanViewSensitiveAppInfoPermission);\n const result: AppInfoResponse = await res.json();\n\n // optional: verify signatures with KMS key\n // const { signingKey } = getKMSKeysForEnvironment(this.config.name);\n\n // Truncate without mutating the original object\n // API returns apps in the same order as the request, so use appIDs[i] as the address\n return result.apps.map((app, i) => {\n // TODO: Implement signature verification\n // const valid = await verifyKMSSignature(appInfo.addresses, signingKey);\n // if (!valid) {\n // throw new Error(`Invalid signature for app ${appIDs[i]}`);\n // }\n\n // Slice derived addresses to requested count\n const evmAddresses = app.addresses?.data?.evmAddresses?.slice(0, count) || [];\n const solanaAddresses = app.addresses?.data?.solanaAddresses?.slice(0, count) || [];\n\n return {\n address: appIDs[i] as Address,\n status: app.app_status,\n ip: app.ip,\n machineType: app.machine_type,\n profile: app.profile,\n metrics: app.metrics,\n evmAddresses,\n solanaAddresses,\n };\n });\n }\n\n /**\n * Get available SKUs (instance types) from UserAPI\n */\n async getSKUs(): Promise<{\n skus: Array<{ sku: string; description: string }>;\n }> {\n const endpoint = `${this.config.userApiServerURL}/skus`;\n const response = await this.makeAuthenticatedRequest(endpoint);\n\n const result = await response.json();\n\n // Transform response to match expected format\n return {\n skus: result.skus || result.SKUs || [],\n };\n }\n\n /**\n * Get logs for an app\n */\n async getLogs(appID: Address): Promise<string> {\n const endpoint = `${this.config.userApiServerURL}/logs/${appID}`;\n const response = await this.makeAuthenticatedRequest(endpoint, CanViewAppLogsPermission);\n return await response.text();\n }\n\n /**\n * Get statuses for apps\n */\n async getStatuses(appIDs: Address[]): Promise<Array<{ address: Address; status: string }>> {\n const endpoint = `${this.config.userApiServerURL}/status`;\n const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(\",\") })}`;\n const response = await this.makeAuthenticatedRequest(url);\n const result = await response.json();\n\n // Transform response to match expected format\n // The API returns an array of app statuses\n const apps = result.apps || result.Apps || [];\n return apps.map((app: any, i: number) => ({\n address: (app.address || appIDs[i]) as Address,\n status: app.status || app.Status || \"\",\n }));\n }\n\n /**\n * Upload app profile information with optional image\n */\n async uploadAppProfile(\n appAddress: Address,\n name: string,\n website?: string,\n description?: string,\n xURL?: string,\n imagePath?: string,\n ): Promise<{\n name: string;\n website?: string;\n description?: string;\n xURL?: string;\n imageURL?: string;\n }> {\n const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}/profile`;\n\n // Build multipart form data using form-data package\n const formData = new FormData();\n\n // Add required name field\n formData.append(\"name\", name);\n\n // Add optional text fields\n if (website) {\n formData.append(\"website\", website);\n }\n if (description) {\n formData.append(\"description\", description);\n }\n if (xURL) {\n formData.append(\"xURL\", xURL);\n }\n\n // Add optional image file\n if (imagePath) {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const fileName = path.basename(imagePath);\n\n // Read file into buffer\n const fileBuffer = fs.readFileSync(imagePath);\n formData.append(\"image\", fileBuffer, fileName);\n }\n\n // Make authenticated POST request\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n ...formData.getHeaders(),\n };\n\n // Add auth headers (Authorization and X-eigenx-expiry)\n if (this.account) {\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60); // 5 minutes\n const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);\n Object.assign(headers, authHeaders);\n }\n\n try {\n // Use axios to post req\n const response: AxiosResponse = await axios.post(endpoint, formData, {\n headers,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n maxContentLength: Infinity, // Allow large file uploads\n maxBodyLength: Infinity, // Allow large file uploads\n });\n\n const status = response.status;\n\n if (status !== 200 && status !== 201) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n\n // Detect Cloudflare challenge page\n if (status === 403 && body.includes(\"Cloudflare\") && body.includes(\"challenge-platform\")) {\n throw new Error(\n `Cloudflare protection is blocking the request. This is likely due to bot detection.\\n` +\n `Status: ${status}`,\n );\n }\n\n throw new Error(\n `UserAPI request failed: ${status} ${status >= 200 && status < 300 ? \"OK\" : \"Error\"} - ${body.substring(0, 500)}${body.length > 500 ? \"...\" : \"\"}`,\n );\n }\n\n return response.data;\n } catch (error: any) {\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to UserAPI at ${endpoint}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.userApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n throw error;\n }\n }\n\n private async makeAuthenticatedRequest(\n url: string,\n permission?: Hex,\n ): Promise<{ json: () => Promise<any>; text: () => Promise<string> }> {\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n };\n // Add auth headers if permission is specified\n if (permission && this.account) {\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60); // 5 minutes\n const authHeaders = await this.generateAuthHeaders(permission, expiry);\n Object.assign(headers, authHeaders);\n }\n\n try {\n // Use axios to match\n const response: AxiosResponse = await axios.get(url, {\n headers,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n });\n\n const status = response.status;\n const statusText = status >= 200 && status < 300 ? \"OK\" : \"Error\";\n\n if (status < 200 || status >= 300) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n throw new Error(`UserAPI request failed: ${status} ${statusText} - ${body}`);\n }\n\n // Return Response-like object for compatibility\n return {\n json: async () => response.data,\n text: async () =>\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data),\n };\n } catch (error: any) {\n // Handle network errors (fetch failed, connection refused, etc.)\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to UserAPI at ${url}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.userApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n // Re-throw other errors as-is\n throw error;\n }\n }\n\n /**\n * Generate authentication headers for UserAPI requests\n */\n private async generateAuthHeaders(\n permission: Hex,\n expiry: bigint,\n ): Promise<Record<string, string>> {\n if (!this.account) {\n throw new Error(\"Private key required for authenticated requests\");\n }\n\n if (!this.rpcUrl) {\n throw new Error(\"RPC URL required for authenticated requests\");\n }\n\n const chain = getChainFromID(this.config.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(this.rpcUrl),\n });\n\n // Calculate permission signature using shared auth utility\n const { signature } = await calculatePermissionSignature({\n permission,\n expiry,\n appControllerAddress: this.config.appControllerAddress as Address,\n publicClient,\n account: this.account,\n });\n\n // Return auth headers\n return {\n Authorization: `Bearer ${stripHexPrefix(signature)}`,\n \"X-eigenx-expiry\": expiry.toString(),\n };\n }\n}\n","/**\n * Shared authentication utilities for API clients\n */\n\nimport { Hex, parseAbi, type Address } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { createPublicClient } from \"viem\";\n\n// Minimal AppController ABI for permission calculation\nconst APP_CONTROLLER_ABI = parseAbi([\n \"function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) view returns (bytes32)\",\n]);\n\nexport interface PermissionSignatureOptions {\n permission: Hex;\n expiry: bigint;\n appControllerAddress: Address;\n publicClient: ReturnType<typeof createPublicClient>;\n account: ReturnType<typeof privateKeyToAccount>;\n}\n\nexport interface PermissionSignatureResult {\n signature: string;\n digest: Hex;\n}\n\n/**\n * Calculate permission digest via AppController contract and sign it with EIP-191\n */\nexport async function calculatePermissionSignature(\n options: PermissionSignatureOptions,\n): Promise<PermissionSignatureResult> {\n const { permission, expiry, appControllerAddress, publicClient, account } = options;\n\n // Calculate permission digest hash using AppController contract\n const digest = (await publicClient.readContract({\n address: appControllerAddress,\n abi: APP_CONTROLLER_ABI,\n functionName: \"calculateApiPermissionDigestHash\",\n args: [permission, expiry],\n })) as Hex;\n\n // Sign the digest using EIP-191 (signMessage handles prefixing automatically)\n const signature = await account.signMessage({\n message: { raw: digest },\n });\n\n return { signature, digest };\n}\n\nexport interface BillingAuthSignatureOptions {\n account: ReturnType<typeof privateKeyToAccount>;\n product: string;\n expiry: bigint;\n}\n\nexport interface BillingAuthSignatureResult {\n signature: Hex;\n expiry: bigint;\n}\n\n/**\n * Sign billing authentication message using EIP-712 typed data\n */\nexport async function calculateBillingAuthSignature(\n options: BillingAuthSignatureOptions,\n): Promise<BillingAuthSignatureResult> {\n const { account, product, expiry } = options;\n\n // Sign using EIP-712 typed data\n const signature = await account.signTypedData({\n domain: {\n name: \"EigenCloud Billing API\",\n version: \"1\",\n },\n types: {\n BillingAuth: [\n { name: \"product\", type: \"string\" },\n { name: \"expiry\", type: \"uint256\" },\n ],\n },\n primaryType: \"BillingAuth\",\n message: {\n product,\n expiry,\n },\n });\n\n return { signature, expiry };\n}\n","/**\n * General utility helpers\n */\n\nimport { extractChain } from \"viem\";\nimport type { Chain } from \"viem\";\nimport { sepolia } from \"viem/chains\";\nimport { SUPPORTED_CHAINS } from \"../constants\";\n\n/**\n * Get a viem Chain object from a chain ID.\n * Supports mainnet (1) and sepolia (11155111), defaults to the fallback chain for unknown chains.\n */\nexport function getChainFromID(chainID: bigint, fallback: Chain = sepolia): Chain {\n const id = Number(chainID) as (typeof SUPPORTED_CHAINS)[number][\"id\"];\n return extractChain({ chains: SUPPORTED_CHAINS, id }) || fallback;\n}\n\n/**\n * Ensure hex string has 0x prefix\n */\nexport function addHexPrefix(value: string): `0x${string}` {\n return (value.startsWith(\"0x\") ? value : `0x${value}`) as `0x${string}`;\n}\n\n/**\n * Remove 0x prefix from hex string if present\n */\nexport function stripHexPrefix(value: string): string {\n return value.startsWith(\"0x\") ? value.slice(2) : value;\n}\n","[\n {\n \"type\": \"constructor\",\n \"inputs\": [\n {\n \"name\": \"_version\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n },\n {\n \"name\": \"_permissionController\",\n \"type\": \"address\",\n \"internalType\": \"contractIPermissionController\"\n },\n {\n \"name\": \"_releaseManager\",\n \"type\": \"address\",\n \"internalType\": \"contractIReleaseManager\"\n },\n {\n \"name\": \"_computeAVSRegistrar\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeAVSRegistrar\"\n },\n {\n \"name\": \"_computeOperator\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeOperator\"\n },\n {\n \"name\": \"_appBeacon\",\n \"type\": \"address\",\n \"internalType\": \"contractIBeacon\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"API_PERMISSION_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"appBeacon\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIBeacon\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"calculateApiPermissionDigestHash\",\n \"inputs\": [\n {\n \"name\": \"permission\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n },\n {\n \"name\": \"expiry\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"calculateAppId\",\n \"inputs\": [\n {\n \"name\": \"deployer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"salt\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"computeAVSRegistrar\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeAVSRegistrar\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"computeOperator\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeOperator\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"createApp\",\n \"inputs\": [\n {\n \"name\": \"salt\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"release\",\n \"type\": \"tuple\",\n \"internalType\": \"structIAppController.Release\",\n \"components\": [\n {\n \"name\": \"rmsRelease\",\n \"type\": \"tuple\",\n \"internalType\": \"structIReleaseManagerTypes.Release\",\n \"components\": [\n {\n \"name\": \"artifacts\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIReleaseManagerTypes.Artifact[]\",\n \"components\": [\n {\n \"name\": \"digest\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"registry\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"name\": \"upgradeByTime\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ]\n },\n {\n \"name\": \"publicEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"encryptedEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"domainSeparator\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getActiveAppCount\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppCreator\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppLatestReleaseBlockNumber\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppOperatorSetId\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppStatus\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getApps\",\n \"inputs\": [\n {\n \"name\": \"offset\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n },\n {\n \"name\": \"appConfigsMem\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIAppController.AppConfig[]\",\n \"components\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"latestReleaseBlockNumber\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"status\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppsByCreator\",\n \"inputs\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"offset\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n },\n {\n \"name\": \"appConfigsMem\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIAppController.AppConfig[]\",\n \"components\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"latestReleaseBlockNumber\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"status\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppsByDeveloper\",\n \"inputs\": [\n {\n \"name\": \"developer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"offset\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n },\n {\n \"name\": \"appConfigsMem\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIAppController.AppConfig[]\",\n \"components\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"latestReleaseBlockNumber\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"status\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getMaxActiveAppsPerUser\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"globalActiveAppCount\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"initialize\",\n \"inputs\": [\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"maxGlobalActiveApps\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"permissionController\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIPermissionController\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"releaseManager\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIReleaseManager\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setMaxActiveAppsPerUser\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setMaxGlobalActiveApps\",\n \"inputs\": [\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"startApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"stopApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"suspend\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"terminateApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"terminateAppByAdmin\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"updateAppMetadataURI\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"metadataURI\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"upgradeApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"release\",\n \"type\": \"tuple\",\n \"internalType\": \"structIAppController.Release\",\n \"components\": [\n {\n \"name\": \"rmsRelease\",\n \"type\": \"tuple\",\n \"internalType\": \"structIReleaseManagerTypes.Release\",\n \"components\": [\n {\n \"name\": \"artifacts\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIReleaseManagerTypes.Artifact[]\",\n \"components\": [\n {\n \"name\": \"digest\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"registry\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"name\": \"upgradeByTime\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ]\n },\n {\n \"name\": \"publicEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"encryptedEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"version\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"event\",\n \"name\": \"AppCreated\",\n \"inputs\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"indexed\": false,\n \"internalType\": \"uint32\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppMetadataURIUpdated\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"metadataURI\",\n \"type\": \"string\",\n \"indexed\": false,\n \"internalType\": \"string\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppStarted\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppStopped\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppSuspended\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppTerminated\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppTerminatedByAdmin\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppUpgraded\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"rmsReleaseId\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"release\",\n \"type\": \"tuple\",\n \"indexed\": false,\n \"internalType\": \"structIAppController.Release\",\n \"components\": [\n {\n \"name\": \"rmsRelease\",\n \"type\": \"tuple\",\n \"internalType\": \"structIReleaseManagerTypes.Release\",\n \"components\": [\n {\n \"name\": \"artifacts\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIReleaseManagerTypes.Artifact[]\",\n \"components\": [\n {\n \"name\": \"digest\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"registry\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"name\": \"upgradeByTime\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ]\n },\n {\n \"name\": \"publicEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"encryptedEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"GlobalMaxActiveAppsSet\",\n \"inputs\": [\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"indexed\": false,\n \"internalType\": \"uint32\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"Initialized\",\n \"inputs\": [\n {\n \"name\": \"version\",\n \"type\": \"uint8\",\n \"indexed\": false,\n \"internalType\": \"uint8\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"MaxActiveAppsSet\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"indexed\": false,\n \"internalType\": \"uint32\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"AccountHasActiveApps\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppAlreadyExists\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppDoesNotExist\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"GlobalMaxActiveAppsExceeded\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidAppStatus\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidPermissions\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidReleaseMetadataURI\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidShortString\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidSignature\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"MaxActiveAppsExceeded\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"MoreThanOneArtifact\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"SignatureExpired\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"StringTooLong\",\n \"inputs\": [\n {\n \"name\": \"str\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n }\n]\n","[\n {\n \"type\": \"function\",\n \"name\": \"acceptAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addPendingAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"canCall\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"caller\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAdmins\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppointeePermissions\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes4[]\",\n \"internalType\": \"bytes4[]\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppointees\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPendingAdmins\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"caller\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isPendingAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"pendingAdmin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"removeAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"removeAppointee\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"removePendingAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setAppointee\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"version\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"event\",\n \"name\": \"AdminRemoved\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AdminSet\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppointeeRemoved\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"indexed\": false,\n \"internalType\": \"bytes4\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppointeeSet\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"indexed\": false,\n \"internalType\": \"bytes4\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"PendingAdminAdded\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"PendingAdminRemoved\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminAlreadyPending\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminAlreadySet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminNotPending\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminNotSet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppointeeAlreadySet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppointeeNotSet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"CannotHaveZeroAdmins\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotAdmin\",\n \"inputs\": []\n }\n]\n","/**\n * Contract watcher\n *\n * Watches app status until it reaches Running state using UserAPI\n */\n\nimport { Address } from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\nimport { UserApiClient } from \"../utils/userapi\";\n\nexport interface WatchUntilRunningOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n clientId?: string;\n}\n\nconst WATCH_POLL_INTERVAL_SECONDS = 5;\nconst APP_STATUS_RUNNING = \"Running\";\nconst APP_STATUS_FAILED = \"Failed\";\n// const APP_STATUS_DEPLOYING = 'Deploying';\n\n/**\n * Watch app until it reaches Running status with IP address\n */\nexport async function watchUntilRunning(\n options: WatchUntilRunningOptions,\n logger: Logger,\n): Promise<string | undefined> {\n const { environmentConfig, appId, privateKey, rpcUrl, clientId } = options;\n\n // Create UserAPI client\n const userApiClient = new UserApiClient(environmentConfig, privateKey, rpcUrl, clientId);\n\n // Track initial status and whether we've seen a change\n let initialStatus: string | undefined;\n let initialIP: string | undefined;\n let hasChanged = false;\n\n // Stop condition: Running status with IP (but only after seeing a change if starting from Running)\n const stopCondition = (status: string, ip: string): boolean => {\n // Capture initial state on first call\n if (!initialStatus) {\n initialStatus = status;\n initialIP = ip;\n }\n\n // Track if status has changed from initial\n if (status !== initialStatus) {\n hasChanged = true;\n }\n\n // Exit on Running with IP, but only if:\n // - We've seen a status change (handles upgrades), OR\n // - Initial status was not Running (handles fresh deploys)\n if (status === APP_STATUS_RUNNING && ip) {\n if (hasChanged || initialStatus !== APP_STATUS_RUNNING) {\n // Only log IP if we didn't have one initially\n if (!initialIP || initialIP === \"No IP assigned\") {\n logger.info(`App is now running with IP: ${ip}`);\n } else {\n logger.info(\"App is now running\");\n }\n return true;\n }\n }\n\n // Check for failure states\n if (status === APP_STATUS_FAILED) {\n throw new Error(`App entered ${status} state`);\n }\n\n return false;\n };\n\n // Main watch loop\n while (true) {\n try {\n // Fetch app info\n const info = await userApiClient.getInfos([appId], 1);\n if (info.length === 0) {\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n continue;\n }\n\n const appInfo = info[0];\n const currentStatus = appInfo.status;\n const currentIP = appInfo.ip || \"\";\n\n // Check stop condition\n if (stopCondition(currentStatus, currentIP)) {\n return currentIP || undefined;\n }\n\n // Wait before next poll\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n } catch (error: any) {\n logger.warn(`Failed to fetch app info: ${error.message}`);\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n }\n }\n}\n\nexport interface WatchUntilUpgradeCompleteOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n clientId?: string;\n}\n\nconst APP_STATUS_STOPPED = \"Stopped\";\n\n/**\n * Watch app until upgrade completes\n * For upgrades, we watch until the app reaches Stopped status (upgrade complete)\n * or Running status (if it was running before upgrade)\n */\nexport async function watchUntilUpgradeComplete(\n options: WatchUntilUpgradeCompleteOptions,\n logger: Logger,\n): Promise<void> {\n const { environmentConfig, appId, privateKey, rpcUrl, clientId } = options;\n\n // Create UserAPI client\n const userApiClient = new UserApiClient(environmentConfig, privateKey, rpcUrl, clientId);\n\n // Track initial status and whether we've seen a change\n let initialStatus: string | undefined;\n let initialIP: string | undefined;\n let hasChanged = false;\n\n // Stop condition: Watch for upgrade completion\n const stopCondition = (status: string, ip: string): boolean => {\n // Capture initial state on first call\n if (!initialStatus) {\n initialStatus = status;\n initialIP = ip;\n\n // If app is already stopped with IP, upgrade is complete\n if (status === APP_STATUS_STOPPED && ip) {\n logger.info(\"App upgrade complete.\");\n logger.info(`Status: ${status}`);\n logger.info(`To start the app, run: ecloud compute app start ${appId}`);\n return true;\n }\n }\n\n // Track if status has changed from initial\n if (status !== initialStatus) {\n hasChanged = true;\n }\n\n // Exit on Stopped status with IP after seeing a change (upgrade complete)\n if (status === APP_STATUS_STOPPED && ip && hasChanged) {\n logger.info(\"App upgrade complete.\");\n logger.info(`Status: ${status}`);\n logger.info(`To start the app, run: ecloud compute app start ${appId}`);\n return true;\n }\n\n // Exit on Running status with IP after seeing a change (upgrade complete and app restarted)\n if (status === APP_STATUS_RUNNING && ip && hasChanged) {\n if (!initialIP || initialIP === \"No IP assigned\") {\n logger.info(`App is now running with IP: ${ip}`);\n } else {\n logger.info(\"App is now running\");\n }\n return true;\n }\n\n // Check for failure states\n if (status === APP_STATUS_FAILED) {\n throw new Error(`App entered ${status} state`);\n }\n\n return false;\n };\n\n // Main watch loop\n while (true) {\n try {\n // Fetch app info\n const info = await userApiClient.getInfos([appId], 1);\n if (info.length === 0) {\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n continue;\n }\n\n const appInfo = info[0];\n const currentStatus = appInfo.status;\n const currentIP = appInfo.ip || \"\";\n\n // Check stop condition\n if (stopCondition(currentStatus, currentIP)) {\n return;\n }\n\n // Wait before next poll\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n } catch (error: any) {\n logger.warn(`Failed to fetch app info: ${error.message}`);\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n }\n }\n}\n\n/**\n * Sleep utility\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Non-interactive validation utilities for SDK\n *\n * These functions validate parameters without any interactive prompts.\n * They either return the validated value or throw an error.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { Address, isAddress } from \"viem\";\nimport { stripHexPrefix, addHexPrefix } from \"./helpers\";\n\n// ==================== App Name Validation ====================\n\n/**\n * Validate app name format\n * @throws Error if name is invalid\n */\nexport function validateAppName(name: string): void {\n if (!name) {\n throw new Error(\"App name cannot be empty\");\n }\n if (name.includes(\" \")) {\n throw new Error(\"App name cannot contain spaces\");\n }\n if (name.length > 50) {\n throw new Error(\"App name cannot be longer than 50 characters\");\n }\n}\n\n// ==================== Image Reference Validation ====================\n\n/**\n * Validate Docker image reference format\n * @returns true if valid, error message string if invalid\n */\nexport function validateImageReference(value: string): true | string {\n if (!value) {\n return \"Image reference cannot be empty\";\n }\n // Basic validation - should contain at least one / and optionally :\n if (!value.includes(\"/\")) {\n return \"Image reference must contain at least one /\";\n }\n return true;\n}\n\n/**\n * Validate image reference and throw if invalid\n * @throws Error if image reference is invalid\n */\nexport function assertValidImageReference(value: string): void {\n const result = validateImageReference(value);\n if (result !== true) {\n throw new Error(result);\n }\n}\n\n/**\n * Extract app name from image reference\n */\nexport function extractAppNameFromImage(imageRef: string): string {\n // Remove registry prefix if present\n const parts = imageRef.split(\"/\");\n let imageName = parts.length > 1 ? parts[parts.length - 1] : imageRef;\n\n // Split image and tag\n if (imageName.includes(\":\")) {\n imageName = imageName.split(\":\")[0];\n }\n\n return imageName;\n}\n\n// ==================== File Path Validation ====================\n\n/**\n * Validate that a file path exists\n * @returns true if valid, error message string if invalid\n */\nexport function validateFilePath(value: string): true | string {\n if (!value) {\n return \"File path cannot be empty\";\n }\n if (!fs.existsSync(value)) {\n return \"File does not exist\";\n }\n return true;\n}\n\n/**\n * Validate file path and throw if invalid\n * @throws Error if file path is invalid or doesn't exist\n */\nexport function assertValidFilePath(value: string): void {\n const result = validateFilePath(value);\n if (result !== true) {\n throw new Error(result);\n }\n}\n\n// ==================== Instance Type Validation ====================\n\n/**\n * Validate instance type SKU against available types\n * @returns the validated SKU\n * @throws Error if SKU is not in the available types list\n */\nexport function validateInstanceTypeSKU(\n sku: string,\n availableTypes: Array<{ sku: string }>,\n): string {\n if (!sku) {\n throw new Error(\"Instance type SKU cannot be empty\");\n }\n\n // Check if SKU is valid\n for (const it of availableTypes) {\n if (it.sku === sku) {\n return sku;\n }\n }\n\n // Build helpful error message with valid options\n const validSKUs = availableTypes.map((it) => it.sku).join(\", \");\n throw new Error(`Invalid instance-type value: ${sku} (must be one of: ${validSKUs})`);\n}\n\n// ==================== Private Key Validation ====================\n\n/**\n * Validate private key format\n * Matches Go's common.ValidatePrivateKey() function\n */\nexport function validatePrivateKeyFormat(key: string): boolean {\n // Remove 0x prefix if present\n const keyWithoutPrefix = stripHexPrefix(key);\n\n // Must be 64 hex characters (32 bytes)\n if (!/^[0-9a-fA-F]{64}$/.test(keyWithoutPrefix)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Validate private key and throw if invalid\n * @throws Error if private key format is invalid\n */\nexport function assertValidPrivateKey(key: string): void {\n if (!key) {\n throw new Error(\"Private key is required\");\n }\n if (!validatePrivateKeyFormat(key)) {\n throw new Error(\n \"Invalid private key format (must be 64 hex characters, optionally prefixed with 0x)\",\n );\n }\n}\n\n// ==================== URL Validation ====================\n\n/**\n * Validate URL format\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateURL(rawURL: string): string | undefined {\n if (!rawURL.trim()) {\n return \"URL cannot be empty\";\n }\n\n try {\n const url = new URL(rawURL);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return \"URL scheme must be http or https\";\n }\n } catch {\n return \"Invalid URL format\";\n }\n\n return undefined;\n}\n\n/**\n * Valid X/Twitter hosts\n */\nconst VALID_X_HOSTS = [\"twitter.com\", \"www.twitter.com\", \"x.com\", \"www.x.com\"];\n\n/**\n * Validate X/Twitter URL format\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateXURL(rawURL: string): string | undefined {\n // First validate as URL\n const urlErr = validateURL(rawURL);\n if (urlErr) {\n return urlErr;\n }\n\n try {\n const url = new URL(rawURL);\n const host = url.hostname.toLowerCase();\n\n // Accept twitter.com and x.com domains\n if (!VALID_X_HOSTS.includes(host)) {\n return \"URL must be a valid X/Twitter URL (x.com or twitter.com)\";\n }\n\n // Ensure it has a path (username/profile)\n if (!url.pathname || url.pathname === \"/\") {\n return \"X URL must include a username or profile path\";\n }\n } catch {\n return \"Invalid X URL format\";\n }\n\n return undefined;\n}\n\n// ==================== Description Validation ====================\n\nconst MAX_DESCRIPTION_LENGTH = 1000;\n\n/**\n * Validate description length\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateDescription(description: string): string | undefined {\n if (!description.trim()) {\n return \"Description cannot be empty\";\n }\n\n if (description.length > MAX_DESCRIPTION_LENGTH) {\n return `Description cannot exceed ${MAX_DESCRIPTION_LENGTH} characters`;\n }\n\n return undefined;\n}\n\n// ==================== Image Path Validation ====================\n\nconst MAX_IMAGE_SIZE = 4 * 1024 * 1024; // 4MB\nconst VALID_IMAGE_EXTENSIONS = [\".jpg\", \".jpeg\", \".png\"];\n\n/**\n * Validate image file path\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateImagePath(filePath: string): string | undefined {\n // Strip quotes that may be added by terminal drag-and-drop\n const cleanedPath = filePath.trim().replace(/^[\"']|[\"']$/g, \"\");\n\n if (!cleanedPath) {\n return \"Image path cannot be empty\";\n }\n\n // Check if file exists\n if (!fs.existsSync(cleanedPath)) {\n return `Image file not found: ${cleanedPath}`;\n }\n\n const stats = fs.statSync(cleanedPath);\n if (stats.isDirectory()) {\n return \"Path is a directory, not a file\";\n }\n\n // Check file size\n if (stats.size > MAX_IMAGE_SIZE) {\n const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);\n return `Image file size (${sizeMB} MB) exceeds maximum allowed size of 4 MB`;\n }\n\n // Check file extension\n const ext = path.extname(cleanedPath).toLowerCase();\n if (!VALID_IMAGE_EXTENSIONS.includes(ext)) {\n return \"Image must be JPG or PNG format\";\n }\n\n return undefined;\n}\n\n// ==================== App ID Validation ====================\n\n/**\n * Validate and normalize app ID address\n * @param appID - App ID (must be a valid address)\n * @returns Normalized app address\n * @throws Error if app ID is not a valid address\n *\n * Note: Name resolution should be handled by CLI before calling SDK functions.\n * The SDK only accepts resolved addresses.\n */\nexport function validateAppID(appID: string | Address): Address {\n if (!appID) {\n throw new Error(\"App ID is required\");\n }\n\n // Normalize the input\n const normalized = typeof appID === \"string\" ? addHexPrefix(appID) : appID;\n\n // Check if it's a valid address\n if (isAddress(normalized)) {\n return normalized as Address;\n }\n\n throw new Error(`Invalid app ID: '${appID}' is not a valid address`);\n}\n\n// ==================== Log Visibility Validation ====================\n\nexport type LogVisibility = \"public\" | \"private\" | \"off\";\n\n/**\n * Validate and convert log visibility setting to internal format\n * @param logVisibility - Log visibility setting\n * @returns Object with logRedirect and publicLogs settings\n * @throws Error if log visibility value is invalid\n */\nexport function validateLogVisibility(logVisibility: LogVisibility): {\n logRedirect: string;\n publicLogs: boolean;\n} {\n switch (logVisibility) {\n case \"public\":\n return { logRedirect: \"always\", publicLogs: true };\n case \"private\":\n return { logRedirect: \"always\", publicLogs: false };\n case \"off\":\n return { logRedirect: \"\", publicLogs: false };\n default:\n throw new Error(\n `Invalid log-visibility value: ${logVisibility} (must be public, private, or off)`,\n );\n }\n}\n\n// ==================== Resource Usage Monitoring Validation ====================\n\nexport type ResourceUsageMonitoring = \"enable\" | \"disable\";\n\n/**\n * Validate and convert resource usage monitoring setting to internal format\n * @param resourceUsageMonitoring - Resource usage monitoring setting\n * @returns The resourceUsageAllow value for the Dockerfile label (\"always\" or \"never\")\n * @throws Error if resource usage monitoring value is invalid\n */\nexport function validateResourceUsageMonitoring(\n resourceUsageMonitoring: ResourceUsageMonitoring | undefined,\n): string {\n // Default to \"enable\" (always) if not specified\n if (!resourceUsageMonitoring) {\n return \"always\";\n }\n\n switch (resourceUsageMonitoring) {\n case \"enable\":\n return \"always\";\n case \"disable\":\n return \"never\";\n default:\n throw new Error(\n `Invalid resource-usage-monitoring value: ${resourceUsageMonitoring} (must be enable or disable)`,\n );\n }\n}\n\n// ==================== Sanitization Functions ====================\n\n/**\n * Check if URL has scheme\n */\nfunction hasScheme(rawURL: string): boolean {\n return rawURL.startsWith(\"http://\") || rawURL.startsWith(\"https://\");\n}\n\n/**\n * Sanitize string (HTML escape and trim)\n */\nexport function sanitizeString(s: string): string {\n return s\n .trim()\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Sanitize URL (add https:// if missing, validate)\n * @throws Error if URL is invalid after sanitization\n */\nexport function sanitizeURL(rawURL: string): string {\n rawURL = rawURL.trim();\n\n // Add https:// if no scheme is present\n if (!hasScheme(rawURL)) {\n rawURL = \"https://\" + rawURL;\n }\n\n // Validate\n const err = validateURL(rawURL);\n if (err) {\n throw new Error(err);\n }\n\n return rawURL;\n}\n\n/**\n * Sanitize X/Twitter URL (handle username-only input, normalize)\n * @throws Error if URL is invalid after sanitization\n */\nexport function sanitizeXURL(rawURL: string): string {\n rawURL = rawURL.trim();\n\n // Handle username-only input (e.g., \"@username\" or \"username\")\n if (!rawURL.includes(\"://\") && !rawURL.includes(\".\")) {\n // Remove @ if present\n const username = rawURL.startsWith(\"@\") ? rawURL.slice(1) : rawURL;\n rawURL = `https://x.com/${username}`;\n } else if (!hasScheme(rawURL)) {\n // Add https:// if URL-like but missing scheme\n rawURL = \"https://\" + rawURL;\n }\n\n // Normalize twitter.com to x.com\n rawURL = rawURL.replace(/twitter\\.com/g, \"x.com\");\n rawURL = rawURL.replace(/www\\.x\\.com/g, \"x.com\");\n\n // Validate\n const err = validateXURL(rawURL);\n if (err) {\n throw new Error(err);\n }\n\n return rawURL;\n}\n\n// ==================== Deploy/Upgrade Parameter Validation ====================\n\nexport interface DeployParams {\n dockerfilePath?: string;\n imageRef?: string;\n appName: string;\n envFilePath?: string;\n instanceType: string;\n logVisibility: LogVisibility;\n}\n\n/**\n * Validate deploy parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateDeployParams(params: Partial<DeployParams>): void {\n // Must have either dockerfilePath or imageRef\n if (!params.dockerfilePath && !params.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for deployment\");\n }\n\n // If imageRef is provided, validate it\n if (params.imageRef) {\n assertValidImageReference(params.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (params.dockerfilePath) {\n assertValidFilePath(params.dockerfilePath);\n }\n\n // App name is required\n if (!params.appName) {\n throw new Error(\"App name is required\");\n }\n validateAppName(params.appName);\n\n // Instance type is required\n if (!params.instanceType) {\n throw new Error(\"Instance type is required\");\n }\n\n // Log visibility is required\n if (!params.logVisibility) {\n throw new Error(\"Log visibility is required (public, private, or off)\");\n }\n validateLogVisibility(params.logVisibility);\n\n // Env file path is optional, but if provided, validate it exists\n if (params.envFilePath && params.envFilePath !== \"\") {\n const result = validateFilePath(params.envFilePath);\n if (result !== true) {\n throw new Error(`Invalid env file: ${result}`);\n }\n }\n}\n\nexport interface UpgradeParams {\n appID: string | Address;\n dockerfilePath?: string;\n imageRef?: string;\n envFilePath?: string;\n instanceType: string;\n logVisibility: LogVisibility;\n}\n\n/**\n * Validate upgrade parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateUpgradeParams(params: Partial<UpgradeParams>): void {\n // App ID is required\n if (!params.appID) {\n throw new Error(\"App ID is required for upgrade\");\n }\n // Validate app ID is a valid address (throws if not)\n validateAppID(params.appID);\n\n // Must have either dockerfilePath or imageRef\n if (!params.dockerfilePath && !params.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for upgrade\");\n }\n\n // If imageRef is provided, validate it\n if (params.imageRef) {\n assertValidImageReference(params.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (params.dockerfilePath) {\n assertValidFilePath(params.dockerfilePath);\n }\n\n // Instance type is required\n if (!params.instanceType) {\n throw new Error(\"Instance type is required\");\n }\n\n // Log visibility is required\n if (!params.logVisibility) {\n throw new Error(\"Log visibility is required (public, private, or off)\");\n }\n validateLogVisibility(params.logVisibility);\n\n // Env file path is optional, but if provided, validate it exists\n if (params.envFilePath && params.envFilePath !== \"\") {\n const result = validateFilePath(params.envFilePath);\n if (result !== true) {\n throw new Error(`Invalid env file: ${result}`);\n }\n }\n}\n\nexport interface CreateAppParams {\n name: string;\n language: string;\n template?: string;\n templateVersion?: string;\n}\n\n/**\n * Validate create app parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateCreateAppParams(params: Partial<CreateAppParams>): void {\n if (!params.name) {\n throw new Error(\"Project name is required\");\n }\n\n // Validate project name (no spaces)\n if (params.name.includes(\" \")) {\n throw new Error(\"Project name cannot contain spaces\");\n }\n\n if (!params.language) {\n throw new Error(\"Language is required\");\n }\n}\n\nexport interface LogsParams {\n appID: string | Address;\n watch?: boolean;\n}\n\n/**\n * Validate logs parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateLogsParams(params: Partial<LogsParams>): void {\n if (!params.appID) {\n throw new Error(\"App ID is required for viewing logs\");\n }\n // Validate app ID is a valid address (throws if not)\n validateAppID(params.appID);\n}\n","/**\n * Preflight checks\n */\n\nimport { Address, createPublicClient, http, PrivateKeyAccount } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nimport { getEnvironmentConfig } from \"../config/environment\";\nimport { addHexPrefix, stripHexPrefix } from \"./helpers\";\n\nimport { Logger, EnvironmentConfig } from \"../types\";\n\nexport interface PreflightContext {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n account: PrivateKeyAccount;\n selfAddress: Address;\n}\n\n/**\n * Do preflight checks - performs early validation of authentication and network connectivity\n */\nexport async function doPreflightChecks(\n options: Partial<{\n privateKey?: string;\n rpcUrl?: string;\n environment?: string;\n }>,\n logger: Logger,\n): Promise<PreflightContext> {\n // 1. Get and validate private key first (fail fast)\n logger.debug(\"Checking authentication...\");\n const privateKey = await getPrivateKeyOrFail(options.privateKey);\n\n // 2. Get environment configuration\n logger.debug(\"Determining environment...\");\n const environmentConfig = getEnvironmentConfig(options.environment || \"sepolia\");\n\n // 3. Get RPC URL (from option, env var, or environment default)\n let rpcUrl = options.rpcUrl;\n if (!rpcUrl) {\n rpcUrl = process.env.RPC_URL ?? environmentConfig.defaultRPCURL;\n }\n if (!rpcUrl) {\n throw new Error(\n `RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`,\n );\n }\n\n // 4. Test network connectivity\n logger.debug(\"Testing network connectivity...\");\n const publicClient = createPublicClient({\n transport: http(rpcUrl),\n });\n\n try {\n // 5. Get chain ID\n const chainID = await publicClient.getChainId();\n if (BigInt(chainID) !== environmentConfig.chainID) {\n throw new Error(`Chain ID mismatch: expected ${environmentConfig.chainID}, got ${chainID}`);\n }\n } catch (err: any) {\n throw new Error(`Cannot connect to ${environmentConfig.name} RPC at ${rpcUrl}: ${err.message}`);\n }\n\n // 6. Create account from private key\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n const selfAddress = account.address;\n\n return {\n privateKey: privateKeyHex,\n rpcUrl,\n environmentConfig,\n account,\n selfAddress,\n };\n}\n\n/**\n * Get private key from options, environment variable, or keyring\n */\nasync function getPrivateKeyOrFail(privateKey?: string): Promise<string> {\n // Check option first\n if (privateKey) {\n validatePrivateKey(privateKey);\n return privateKey;\n }\n\n // Check environment variable\n if (process.env.PRIVATE_KEY) {\n validatePrivateKey(process.env.PRIVATE_KEY);\n return process.env.PRIVATE_KEY;\n }\n\n // TODO: Check keyring (OS keyring integration)\n // For now, throw error with instructions\n throw new Error(\n `private key required. Please provide it via:\n • Option: privateKey in deploy options\n • Environment: export PRIVATE_KEY=YOUR_KEY\n • Keyring: (not yet implemented)`,\n );\n}\n\n/**\n * Validate private key format\n */\nfunction validatePrivateKey(key: string): void {\n const cleaned = stripHexPrefix(key);\n if (!/^[0-9a-fA-F]{64}$/.test(cleaned)) {\n throw new Error(\"Invalid private key format (must be 64 hex characters)\");\n }\n}\n","/**\n * No-op telemetry client implementation\n */\n\nimport { TelemetryClient, Metric } from \"./types\";\n\n/**\n * NoopClient implements the TelemetryClient interface with no-op methods\n */\nexport class NoopClient implements TelemetryClient {\n /**\n * AddMetric implements the TelemetryClient interface\n */\n async addMetric(_metric: Metric): Promise<void> {\n // No-op\n }\n\n /**\n * Close implements the TelemetryClient interface\n */\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * Check if a client is a NoopClient\n */\nexport function isNoopClient(client: TelemetryClient): boolean {\n return client instanceof NoopClient;\n}\n","/**\n * PostHog telemetry client implementation\n *\n * Uses the official posthog-node library\n */\n\nimport { PostHog } from \"posthog-node\";\nimport { TelemetryClient, Metric, AppEnvironment } from \"./types\";\n\n/**\n * PostHogClient implements the TelemetryClient interface using posthog-node\n */\nexport class PostHogClient implements TelemetryClient {\n private readonly client: PostHog;\n private readonly namespace: string;\n private readonly appEnvironment: AppEnvironment;\n\n constructor(environment: AppEnvironment, namespace: string, apiKey: string, endpoint?: string) {\n this.namespace = namespace;\n this.appEnvironment = environment;\n\n // Initialize PostHog client\n // posthog-node expects the full URL for the host option\n const host = endpoint || \"https://us.i.posthog.com\";\n\n this.client = new PostHog(apiKey, {\n host: host,\n flushAt: 1, // Flush immediately for CLI/SDK usage\n flushInterval: 0, // Disable interval flushing\n });\n\n // Identify the user with their UUID\n this.client.identify({\n distinctId: environment.userUUID,\n properties: {\n os: environment.os,\n arch: environment.arch,\n ...(environment.cliVersion ? { cliVersion: environment.cliVersion } : {}),\n },\n });\n }\n\n /**\n * AddMetric implements the TelemetryClient interface\n */\n async addMetric(metric: Metric): Promise<void> {\n // Never throw errors from telemetry operations\n try {\n // Create properties map starting with base properties\n const props: Record<string, any> = {\n name: metric.name,\n value: metric.value,\n };\n\n // Add metric dimensions\n for (const [k, v] of Object.entries(metric.dimensions)) {\n props[k] = v;\n }\n\n // Capture event using the namespace as the event name\n // With flushAt: 1, events are automatically flushed after each capture\n this.client.capture({\n distinctId: this.appEnvironment.userUUID,\n event: this.namespace,\n properties: props,\n });\n } catch {\n // Silently ignore telemetry errors\n }\n }\n\n /**\n * Close implements the TelemetryClient interface\n */\n async close(): Promise<void> {\n try {\n // Shutdown PostHog client and flush any pending events\n // shutdown() is synchronous but internally handles async cleanup\n this.client.shutdown();\n } catch {\n // Silently ignore errors during shutdown\n }\n }\n}\n\n/**\n * Embedded PostHog API key (can be exposed in TypeScript)\n * This can be set at build time or overridden via environment variable\n */\n// @ts-ignore - POSTHOG_API_KEY_BUILD_TIME is injected at build time by tsup\ndeclare const POSTHOG_API_KEY_BUILD_TIME: string | undefined;\n\n/**\n * Get PostHog API key from environment variable or build-time constant\n */\nexport function getPostHogAPIKey(): string | undefined {\n // Priority order:\n // 1. Environment variable\n // 2. Build-time constant (set at build time)\n // Check environment variable first\n if (process.env.ECLOUD_POSTHOG_KEY) {\n return process.env.ECLOUD_POSTHOG_KEY;\n }\n\n // Return build-time constant if available\n // @ts-ignore - POSTHOG_API_KEY_BUILD_TIME is injected at build time\n return typeof POSTHOG_API_KEY_BUILD_TIME !== \"undefined\" ? POSTHOG_API_KEY_BUILD_TIME : undefined;\n}\n\n/**\n * Get PostHog endpoint from environment variable or default\n */\nexport function getPostHogEndpoint(): string {\n return process.env.ECLOUD_POSTHOG_ENDPOINT || \"https://us.i.posthog.com\";\n}\n","/**\n * Telemetry module for ECloud SDK and CLI\n *\n * Provides telemetry functionality matching the Go implementation.\n * Supports both \"ecloud-cli\" and \"ecloud-sdk\" namespaces.\n */\n\nimport { TelemetryClient, Metric, AppEnvironment } from \"./types\";\nimport { NoopClient, isNoopClient } from \"./noop\";\nimport { PostHogClient, getPostHogAPIKey, getPostHogEndpoint } from \"./posthog\";\nimport * as os from \"os\";\n\nexport * from \"./types\";\nexport * from \"./metricsContext\";\nexport * from \"./noop\";\nexport * from \"./posthog\";\nexport * from \"./wrapper\";\n\n/**\n * Options for creating a telemetry client\n */\nexport interface TelemetryClientOptions {\n /**\n * Whether telemetry is enabled (only enabled if explicitly set to true, defaults to disabled)\n */\n telemetryEnabled?: boolean;\n /**\n * PostHog API key (if not provided, will check environment variables)\n */\n apiKey?: string;\n /**\n * PostHog endpoint (if not provided, will use default)\n */\n endpoint?: string;\n}\n\n/**\n * Create a telemetry client\n *\n * @param environment - Application environment information (must include userUUID)\n * @param namespace - Namespace for telemetry events (\"ecloud-cli\" or \"ecloud-sdk\")\n * @param options - Optional telemetry client options\n * @returns TelemetryClient instance (NoopClient if telemetry is disabled or no API key)\n */\nexport function createTelemetryClient(\n environment: AppEnvironment,\n namespace: \"ecloud-cli\" | \"ecloud-sdk\",\n options?: TelemetryClientOptions,\n): TelemetryClient {\n // Check if telemetry is enabled\n // Only enabled if explicitly set to true\n // If undefined or false, telemetry is disabled\n const telemetryEnabled = options?.telemetryEnabled === true;\n\n // If telemetry is disabled, return noop client\n if (!telemetryEnabled) {\n return new NoopClient();\n }\n\n // Get API key from options, environment variable, or return noop\n const resolvedApiKey = options?.apiKey || getPostHogAPIKey();\n if (!resolvedApiKey) {\n // No API key available, return noop client\n return new NoopClient();\n }\n\n // Get endpoint from options or environment variable\n const endpoint = options?.endpoint || getPostHogEndpoint();\n\n try {\n return new PostHogClient(environment, namespace, resolvedApiKey, endpoint);\n } catch {\n // If initialization fails, return noop client\n return new NoopClient();\n }\n}\n\n/**\n * Create an AppEnvironment from current system information\n *\n * @param userUUID - User UUID for identification (required - no I/O in SDK)\n * @param cliVersion - Optional CLI version (for CLI usage)\n * @param osOverride - Optional OS override (defaults to current platform)\n * @param archOverride - Optional architecture override (defaults to current architecture)\n * @returns AppEnvironment with user UUID, OS, and architecture\n */\nexport function createAppEnvironment(\n userUUID: string,\n cliVersion?: string,\n osOverride?: string,\n archOverride?: string,\n): AppEnvironment {\n return {\n userUUID,\n cliVersion,\n os: osOverride || os.platform(),\n arch: archOverride || os.arch(),\n };\n}\n\n/**\n * Emit metrics from a metrics context\n *\n * @param client - Telemetry client to use\n * @param context - Metrics context containing metrics to emit\n * @returns Promise that resolves when all metrics are emitted\n */\nexport async function emitMetrics(\n client: TelemetryClient,\n context: {\n metrics: Metric[];\n properties: Record<string, string>;\n },\n): Promise<void> {\n if (isNoopClient(client)) {\n return;\n }\n\n // Emit each metric with properties merged into dimensions\n for (const metric of context.metrics) {\n const dimensions = {\n ...metric.dimensions,\n ...context.properties,\n };\n\n const metricWithProperties: Metric = {\n ...metric,\n dimensions,\n };\n\n try {\n await client.addMetric(metricWithProperties);\n } catch {\n // Silently ignore telemetry errors\n }\n }\n}\n","/**\n * MetricsContext management\n */\n\nimport { MetricsContext } from \"./types\";\n\n/**\n * Create a new metrics context\n */\nexport function createMetricsContext(): MetricsContext {\n return {\n startTime: new Date(),\n metrics: [],\n properties: {},\n };\n}\n\n/**\n * Add a metric to the context without dimensions\n */\nexport function addMetric(context: MetricsContext, name: string, value: number): void {\n addMetricWithDimensions(context, name, value, {});\n}\n\n/**\n * Add a metric to the context with dimensions\n */\nexport function addMetricWithDimensions(\n context: MetricsContext,\n name: string,\n value: number,\n dimensions: Record<string, string>,\n): void {\n context.metrics.push({\n name,\n value,\n dimensions,\n });\n}\n","/**\n * Telemetry wrapper utilities for SDK functions\n *\n * Provides helpers to wrap SDK function execution with telemetry tracking\n */\n\nimport {\n createTelemetryClient,\n createAppEnvironment,\n createMetricsContext,\n addMetric,\n addMetricWithDimensions,\n emitMetrics,\n} from \"./index\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Generate a random UUID for telemetry identification\n * Used when userUUID is not provided (SDK usage outside CLI)\n */\nfunction generateRandomUUID(): string {\n return randomUUID();\n}\n\n/**\n * Options for telemetry wrapper\n */\nexport interface TelemetryWrapperOptions {\n /**\n * Function name for telemetry (e.g., \"deploy\", \"upgrade\", \"createApp\")\n */\n functionName: string;\n /**\n * Skip telemetry if true (used when called from CLI)\n */\n skipTelemetry?: boolean;\n /**\n * Additional properties to include in telemetry\n */\n properties?: Record<string, string>;\n /**\n * User UUID for identification (required if skipTelemetry is false)\n * If not provided and telemetry is enabled, will generate a random UUID for this session\n */\n userUUID?: string;\n /**\n * Whether telemetry is enabled (defaults to true if not provided)\n */\n telemetryEnabled?: boolean;\n /**\n * PostHog API key (optional, will check environment variables if not provided)\n */\n apiKey?: string;\n /**\n * PostHog endpoint (optional, will use default if not provided)\n */\n endpoint?: string;\n}\n\n/**\n * Wrap a function execution with telemetry\n *\n * @param options - Telemetry wrapper options\n * @param action - The function to execute\n * @returns The result of the action\n */\nexport async function withSDKTelemetry<T>(\n options: TelemetryWrapperOptions,\n action: () => Promise<T>,\n): Promise<T> {\n // Skip telemetry if requested (e.g., when called from CLI)\n if (options.skipTelemetry) {\n return action();\n }\n\n // Generate a random UUID if not provided (for SDK usage outside CLI)\n // This ensures each SDK session has a unique identifier\n const userUUID = options.userUUID || generateRandomUUID();\n\n const environment = createAppEnvironment(userUUID);\n const client = createTelemetryClient(environment, \"ecloud-sdk\", {\n telemetryEnabled: options.telemetryEnabled,\n apiKey: options.apiKey,\n endpoint: options.endpoint,\n });\n const metrics = createMetricsContext();\n\n // Set source to identify SDK usage\n metrics.properties[\"source\"] = \"ecloud-sdk\";\n\n // Set function name in properties\n metrics.properties[\"function\"] = options.functionName;\n\n // Add any additional properties\n if (options.properties) {\n Object.assign(metrics.properties, options.properties);\n }\n\n // Add initial count metric\n addMetric(metrics, \"Count\", 1);\n\n let actionError: Error | undefined;\n let result: T;\n\n try {\n result = await action();\n return result;\n } catch (err) {\n actionError = err instanceof Error ? err : new Error(String(err));\n throw err;\n } finally {\n // Add result metric\n const resultValue = actionError ? \"Failure\" : \"Success\";\n const dimensions: Record<string, string> = {};\n if (actionError) {\n dimensions[\"error\"] = actionError.message;\n }\n addMetricWithDimensions(metrics, resultValue, 1, dimensions);\n\n // Add duration metric\n const duration = Date.now() - metrics.startTime.getTime();\n addMetric(metrics, \"DurationMilliseconds\", duration);\n\n // Emit all metrics\n try {\n await emitMetrics(client, metrics);\n await client.close();\n } catch {\n // Silently ignore telemetry errors\n }\n }\n}\n","/**\n * Main deploy function\n *\n * This is the main entry point for deploying applications to ecloud TEE.\n * It orchestrates all the steps: build, push, encrypt, and deploy on-chain.\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport { DeployResult, Logger, EnvironmentConfig } from \"../../../common/types\";\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport { ensureDockerIsRunning } from \"../../../common/docker/build\";\nimport { prepareRelease } from \"../../../common/release/prepare\";\nimport {\n deployApp,\n calculateAppID,\n getMaxActiveAppsPerUser,\n getActiveAppCount,\n prepareDeployBatch,\n executeDeployBatch,\n type PreparedDeployBatch,\n} from \"../../../common/contract/caller\";\nimport { estimateBatchGas } from \"../../../common/contract/eip7702\";\nimport { type GasEstimate } from \"../../../common/contract/caller\";\nimport { watchUntilRunning } from \"../../../common/contract/watcher\";\nimport {\n validateAppName,\n validateLogVisibility,\n validateResourceUsageMonitoring,\n assertValidImageReference,\n assertValidFilePath,\n LogVisibility,\n ResourceUsageMonitoring,\n} from \"../../../common/utils/validation\";\nimport { doPreflightChecks, PreflightContext } from \"../../../common/utils/preflight\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\n/**\n * Required deploy options for SDK (non-interactive)\n */\nexport interface SDKDeployOptions {\n /** Private key for signing transactions (hex string with or without 0x prefix) */\n privateKey: string;\n /** RPC URL for blockchain connection - optional, uses environment default if not provided */\n rpcUrl?: string;\n /** Environment name (e.g., 'sepolia', 'mainnet-alpha') - defaults to 'sepolia' */\n environment?: string;\n /** Path to Dockerfile (if building from Dockerfile) - either this or imageRef is required */\n dockerfilePath?: string;\n /** Image reference (registry/path:tag) - either this or dockerfilePath is required */\n imageRef?: string;\n /** Path to .env file - optional */\n envFilePath?: string;\n /** App name - required */\n appName: string;\n /** Instance type SKU - required */\n instanceType: string;\n /** Log visibility setting - required */\n logVisibility: LogVisibility;\n /** Resource usage monitoring setting - optional, defaults to 'enable' */\n resourceUsageMonitoring?: ResourceUsageMonitoring;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n /** Skip telemetry (used when called from CLI) - optional */\n skipTelemetry?: boolean;\n}\n\n/**\n * Prepared deployment ready for gas estimation and execution\n */\nexport interface PreparedDeploy {\n /** The prepared batch (executions, clients, etc.) */\n batch: PreparedDeployBatch;\n /** App name */\n appName: string;\n /** Final image reference */\n imageRef: string;\n /** Preflight context for post-deploy operations */\n preflightCtx: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n };\n}\n\n/**\n * Result from prepareDeploy - includes prepared batch and gas estimate\n */\nexport interface PrepareDeployResult {\n /** Prepared deployment state */\n prepared: PreparedDeploy;\n /** Gas estimate for the batch transaction */\n gasEstimate: GasEstimate;\n}\n\n/**\n * Validate deploy options and throw descriptive errors for missing/invalid params\n */\nfunction validateDeployOptions(options: SDKDeployOptions): void {\n // Private key is required\n if (!options.privateKey) {\n throw new Error(\"privateKey is required for deployment\");\n }\n\n // Must have either dockerfilePath or imageRef\n if (!options.dockerfilePath && !options.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for deployment\");\n }\n\n // If imageRef is provided, validate it\n if (options.imageRef) {\n assertValidImageReference(options.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (options.dockerfilePath) {\n assertValidFilePath(options.dockerfilePath);\n }\n\n // App name is required\n if (!options.appName) {\n throw new Error(\"appName is required for deployment\");\n }\n validateAppName(options.appName);\n\n // Instance type is required\n if (!options.instanceType) {\n throw new Error(\"instanceType is required for deployment\");\n }\n\n // Log visibility is required\n if (!options.logVisibility) {\n throw new Error(\"logVisibility is required (must be 'public', 'private', or 'off')\");\n }\n // Validate log visibility value\n validateLogVisibility(options.logVisibility);\n}\n\n/**\n * Deploy an application to ECloud TEE\n *\n * This function is non-interactive and requires all parameters to be provided explicitly.\n *\n * Flow:\n * 1. Validate all required parameters\n * 2. Preflight checks (auth, network, etc.)\n * 3. Check quota availability\n * 4. Ensure Docker is running\n * 5. Generate random salt and calculate app ID\n * 6. Prepare the release (includes build/push if needed)\n * 7. Deploy the app on-chain\n * 8. Watch until app is running\n *\n * @param options - Required deployment options\n * @param logger - Optional logger instance\n * @returns DeployResult with appID, txHash, appName, imageRef, and ipAddress\n * @throws Error if required parameters are missing or invalid\n */\nexport async function deploy(\n options: SDKDeployOptions,\n logger: Logger = defaultLogger,\n): Promise<DeployResult> {\n return withSDKTelemetry(\n {\n functionName: \"deploy\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Validate all required parameters upfront\n validateDeployOptions(options);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 2. Do preflight checks (auth, network, etc.)\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 3. Check quota availability\n logger.debug(\"Checking quota availability...\");\n await checkQuotaAvailable(preflightCtx);\n\n // 4. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const appName = options.appName;\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 5. Generate random salt\n const salt = generateRandomSalt();\n logger.debug(`Generated salt: ${Buffer.from(salt).toString(\"hex\")}`);\n\n // 6. Get app ID (calculate from salt and address)\n logger.debug(\"Calculating app ID...\");\n const appIDToBeDeployed = await calculateAppID(\n preflightCtx.privateKey,\n options.rpcUrl || preflightCtx.rpcUrl,\n preflightCtx.environmentConfig,\n salt,\n );\n logger.info(``);\n logger.info(`App ID: ${appIDToBeDeployed}`);\n logger.info(``);\n\n // 7. Prepare the release (includes build/push if needed, with automatic retry on permission errors)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appIDToBeDeployed,\n },\n logger,\n );\n\n // 8. Deploy the app\n logger.info(\"Deploying on-chain...\");\n const deployResult = await deployApp(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n salt,\n release,\n publicLogs,\n imageRef: finalImageRef,\n gas: options.gas,\n },\n logger,\n );\n\n // 9. Watch until app is running\n logger.info(\"Waiting for app to start...\");\n const ipAddress = await watchUntilRunning(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: deployResult.appId,\n },\n logger,\n );\n\n return {\n appId: deployResult.appId,\n txHash: deployResult.txHash,\n appName,\n imageRef: finalImageRef,\n ipAddress,\n };\n },\n );\n}\n\n/**\n * Check quota availability - verifies that the user has deployment quota available\n * by checking their allowlist status on the contract\n */\nasync function checkQuotaAvailable(preflightCtx: PreflightContext): Promise<void> {\n const rpcUrl = preflightCtx.rpcUrl;\n const environmentConfig = preflightCtx.environmentConfig;\n const userAddress = preflightCtx.selfAddress;\n\n // Check user's quota limit from contract\n let maxQuota: number;\n try {\n maxQuota = await getMaxActiveAppsPerUser(rpcUrl, environmentConfig, userAddress);\n } catch (err: any) {\n throw new Error(`failed to get quota limit: ${err.message}`);\n }\n\n // If quota is 0, user needs to subscribe\n if (maxQuota === 0) {\n throw new Error(\n \"no app quota available. Run 'ecloud billing subscribe' to enable app deployment\",\n );\n }\n\n // Check current active app count from contract\n let activeCount: number;\n try {\n activeCount = await getActiveAppCount(rpcUrl, environmentConfig, userAddress);\n } catch (err: any) {\n throw new Error(`failed to get active app count: ${err.message}`);\n }\n\n // Check if quota is reached\n if (activeCount >= maxQuota) {\n throw new Error(\n `app quota reached for ${environmentConfig.name} (${activeCount}/${maxQuota}). Please contact the Eigen team at eigencloud_support@eigenlabs.org for additional capacity`,\n );\n }\n}\n\n/**\n * Generate random 32-byte salt\n */\nfunction generateRandomSalt(): Uint8Array {\n const salt = new Uint8Array(32);\n crypto.getRandomValues(salt);\n return salt;\n}\n\n/**\n * Prepare deployment - does all work up to the transaction\n *\n * This allows CLI to:\n * 1. Call prepareDeploy to build image, prepare release, get gas estimate\n * 2. Prompt user to confirm the cost\n * 3. Call executeDeploy with confirmed gas params\n */\nexport async function prepareDeploy(\n options: Omit<SDKDeployOptions, \"gas\"> & { skipTelemetry?: boolean },\n logger: Logger = defaultLogger,\n): Promise<PrepareDeployResult> {\n return withSDKTelemetry(\n {\n functionName: \"prepareDeploy\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Validate all required parameters upfront\n validateDeployOptions(options as SDKDeployOptions);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 2. Do preflight checks (auth, network, etc.)\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 3. Check quota availability\n logger.debug(\"Checking quota availability...\");\n await checkQuotaAvailable(preflightCtx);\n\n // 4. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const appName = options.appName;\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 5. Generate random salt\n const salt = generateRandomSalt();\n logger.debug(`Generated salt: ${Buffer.from(salt).toString(\"hex\")}`);\n\n // 6. Get app ID (calculate from salt and address)\n logger.debug(\"Calculating app ID...\");\n const appIDToBeDeployed = await calculateAppID(\n preflightCtx.privateKey,\n options.rpcUrl || preflightCtx.rpcUrl,\n preflightCtx.environmentConfig,\n salt,\n );\n logger.info(``);\n logger.info(`App ID: ${appIDToBeDeployed}`);\n logger.info(``);\n\n // 7. Prepare the release (includes build/push if needed)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appIDToBeDeployed,\n },\n logger,\n );\n\n // 8. Prepare the deploy batch (creates executions without sending)\n logger.debug(\"Preparing deploy batch...\");\n const batch = await prepareDeployBatch(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n salt,\n release,\n publicLogs,\n },\n logger,\n );\n\n // 9. Estimate gas for the batch\n logger.debug(\"Estimating gas...\");\n const gasEstimate = await estimateBatchGas({\n publicClient: batch.publicClient,\n environmentConfig: batch.environmentConfig,\n executions: batch.executions,\n });\n\n return {\n prepared: {\n batch,\n appName,\n imageRef: finalImageRef,\n preflightCtx: {\n privateKey: preflightCtx.privateKey,\n rpcUrl: preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n },\n },\n gasEstimate,\n };\n },\n );\n}\n\n/**\n * Execute a prepared deployment\n *\n * Call this after prepareDeploy and user confirmation.\n * Note: This only submits the on-chain transaction. Call watchDeployment separately\n * to wait for the app to be running.\n */\nexport async function executeDeploy(\n prepared: PreparedDeploy,\n gas: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint } | undefined,\n logger: Logger = defaultLogger,\n skipTelemetry?: boolean,\n): Promise<DeployResult> {\n return withSDKTelemetry(\n {\n functionName: \"executeDeploy\",\n skipTelemetry: skipTelemetry,\n },\n async () => {\n // Execute the batch transaction\n logger.info(\"Deploying on-chain...\");\n const { appId, txHash } = await executeDeployBatch(prepared.batch, gas, logger);\n\n return {\n appId,\n txHash,\n appName: prepared.appName,\n imageRef: prepared.imageRef,\n };\n },\n );\n}\n\n/**\n * Watch a deployment until the app is running\n *\n * Call this after executeDeploy to wait for the app to be provisioned.\n * Can be called separately to allow for intermediate operations (e.g., profile upload).\n */\nexport async function watchDeployment(\n appId: string,\n privateKey: string,\n rpcUrl: string,\n environment: string,\n logger: Logger = defaultLogger,\n clientId?: string,\n skipTelemetry?: boolean,\n): Promise<string | undefined> {\n return withSDKTelemetry(\n {\n functionName: \"watchDeployment\",\n skipTelemetry: skipTelemetry,\n properties: {\n environment,\n },\n },\n async () => {\n const environmentConfig = getEnvironmentConfig(environment);\n\n logger.info(\"Waiting for app to start...\");\n return watchUntilRunning(\n {\n privateKey,\n rpcUrl,\n environmentConfig,\n appId: appId as `0x${string}`,\n clientId,\n },\n logger,\n );\n },\n );\n}\n\n// Re-export for convenience\nexport { extractAppNameFromImage } from \"../../../common/utils/validation\";\n","/**\n * Permission checking utilities\n */\n\nimport { Address, createPublicClient, http, Hex } from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\nimport PermissionControllerABI from \"../abis/PermissionController.json\";\nimport { getChainFromID } from \"./helpers\";\n\n// Permission constants (matching Go version)\nconst AnyoneCanCallAddress = \"0x493219d9949348178af1f58740655951a8cd110c\" as Address;\nconst ApiPermissionsTarget = \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address;\nconst CanViewAppLogsPermission = \"0x2fd3f2fe\" as Hex;\n\n/**\n * Check if an app currently has public log viewing permissions\n */\nexport async function checkAppLogPermission(\n preflightCtx: {\n environmentConfig: EnvironmentConfig;\n rpcUrl: string;\n },\n appAddress: Address,\n logger: Logger,\n): Promise<boolean> {\n const chain = getChainFromID(preflightCtx.environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(preflightCtx.rpcUrl),\n });\n\n try {\n // Call the canCall method on PermissionController\n const canCall = await publicClient.readContract({\n address: preflightCtx.environmentConfig.permissionControllerAddress as Address,\n abi: PermissionControllerABI,\n functionName: \"canCall\",\n args: [appAddress, AnyoneCanCallAddress, ApiPermissionsTarget, CanViewAppLogsPermission],\n });\n\n return canCall as boolean;\n } catch (err: any) {\n logger.warn(`Failed to check log permission: ${err.message}. Assuming private logs.`);\n // Default to false (private) on error\n return false;\n }\n}\n","/**\n * Main upgrade function\n *\n * This is the main entry point for upgrading existing applications on ecloud TEE.\n * It orchestrates all the steps: build, push, encrypt, and upgrade on-chain.\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport { Address } from \"viem\";\nimport { Logger, EnvironmentConfig } from \"../../../common/types\";\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport { ensureDockerIsRunning } from \"../../../common/docker/build\";\nimport { prepareRelease } from \"../../../common/release/prepare\";\nimport {\n upgradeApp,\n prepareUpgradeBatch,\n executeUpgradeBatch,\n type PreparedUpgradeBatch,\n type GasEstimate,\n} from \"../../../common/contract/caller\";\nimport { estimateBatchGas } from \"../../../common/contract/eip7702\";\nimport { watchUntilUpgradeComplete } from \"../../../common/contract/watcher\";\nimport {\n validateAppID,\n validateLogVisibility,\n validateResourceUsageMonitoring,\n assertValidImageReference,\n assertValidFilePath,\n LogVisibility,\n ResourceUsageMonitoring,\n} from \"../../../common/utils/validation\";\nimport { doPreflightChecks } from \"../../../common/utils/preflight\";\nimport { checkAppLogPermission } from \"../../../common/utils/permissions\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\n/**\n * Required upgrade options for SDK (non-interactive)\n */\nexport interface SDKUpgradeOptions {\n /** App ID to upgrade - required */\n appId: string | Address;\n /** Private key for signing transactions (hex string with or without 0x prefix) */\n privateKey: string;\n /** RPC URL for blockchain connection - optional, uses environment default if not provided */\n rpcUrl?: string;\n /** Environment name (e.g., 'sepolia', 'mainnet-alpha') - defaults to 'sepolia' */\n environment?: string;\n /** Path to Dockerfile (if building from Dockerfile) - either this or imageRef is required */\n dockerfilePath?: string;\n /** Image reference (registry/path:tag) - either this or dockerfilePath is required */\n imageRef?: string;\n /** Path to .env file - optional */\n envFilePath?: string;\n /** Instance type SKU - required */\n instanceType: string;\n /** Log visibility setting - required */\n logVisibility: LogVisibility;\n /** Resource usage monitoring setting - optional, defaults to 'enable' */\n resourceUsageMonitoring?: ResourceUsageMonitoring;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n /** Skip telemetry (used when called from CLI) - optional */\n skipTelemetry?: boolean;\n}\n\nexport interface UpgradeResult {\n /** App ID (contract address) */\n appId: string;\n /** Final image reference */\n imageRef: string;\n /** Transaction hash */\n txHash: `0x${string}`;\n}\n\n/**\n * Prepared upgrade ready for gas estimation and execution\n */\nexport interface PreparedUpgrade {\n /** The prepared batch (executions, clients, etc.) */\n batch: PreparedUpgradeBatch;\n /** App ID being upgraded */\n appId: string;\n /** Final image reference */\n imageRef: string;\n /** Preflight context for post-upgrade operations */\n preflightCtx: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n };\n}\n\n/**\n * Result from prepareUpgrade - includes prepared batch and gas estimate\n */\nexport interface PrepareUpgradeResult {\n /** Prepared upgrade state */\n prepared: PreparedUpgrade;\n /** Gas estimate for the batch transaction */\n gasEstimate: GasEstimate;\n}\n\n/**\n * Validate upgrade options and throw descriptive errors for missing/invalid params\n */\nfunction validateUpgradeOptions(options: SDKUpgradeOptions): Address {\n // Private key is required\n if (!options.privateKey) {\n throw new Error(\"privateKey is required for upgrade\");\n }\n\n // App ID is required\n if (!options.appId) {\n throw new Error(\"appId is required for upgrade\");\n }\n // Validate app ID (must be a valid address - name resolution is done by CLI)\n const resolvedAppID = validateAppID(options.appId);\n\n // Must have either dockerfilePath or imageRef\n if (!options.dockerfilePath && !options.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for upgrade\");\n }\n\n // If imageRef is provided, validate it\n if (options.imageRef) {\n assertValidImageReference(options.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (options.dockerfilePath) {\n assertValidFilePath(options.dockerfilePath);\n }\n\n // Instance type is required\n if (!options.instanceType) {\n throw new Error(\"instanceType is required for upgrade\");\n }\n\n // Log visibility is required\n if (!options.logVisibility) {\n throw new Error(\"logVisibility is required (must be 'public', 'private', or 'off')\");\n }\n // Validate log visibility value\n validateLogVisibility(options.logVisibility);\n\n return resolvedAppID;\n}\n\n/**\n * Upgrade an existing application on ECloud TEE\n *\n * This function is non-interactive and requires all parameters to be provided explicitly.\n *\n * Flow:\n * 1. Validate all required parameters\n * 2. Preflight checks (auth, network, etc.)\n * 3. Ensure Docker is running\n * 4. Prepare the release (includes build/push if needed)\n * 5. Check current permission state and determine if change is needed\n * 6. Upgrade the app on-chain\n * 7. Watch until upgrade completes\n *\n * @param options - Required upgrade options\n * @param logger - Optional logger instance\n * @returns UpgradeResult with appID, imageRef, and txHash\n * @throws Error if required parameters are missing or invalid\n */\nexport async function upgrade(\n options: SDKUpgradeOptions,\n logger: Logger = defaultLogger,\n): Promise<UpgradeResult> {\n return withSDKTelemetry(\n {\n functionName: \"upgrade\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Do preflight checks (auth, network, etc.) first\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 2. Validate all required parameters upfront\n const appID = validateUpgradeOptions(options);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 3. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 4. Prepare the release (includes build/push if needed, with automatic retry on permission errors)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID as string,\n },\n logger,\n );\n\n // 5. Check current permission state and determine if change is needed\n logger.debug(\"Checking current log permission state...\");\n const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);\n const needsPermissionChange = currentlyPublic !== publicLogs;\n\n // 6. Upgrade the app\n logger.info(\"Upgrading on-chain...\");\n const txHash = await upgradeApp(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n release,\n publicLogs,\n needsPermissionChange,\n imageRef: finalImageRef,\n gas: options.gas,\n },\n logger,\n );\n\n // 7. Watch until upgrade completes\n logger.info(\"Waiting for upgrade to complete...\");\n await watchUntilUpgradeComplete(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n },\n logger,\n );\n\n return {\n appId: appID as string,\n imageRef: finalImageRef,\n txHash,\n };\n },\n );\n}\n\n/**\n * Prepare upgrade - does all work up to the transaction\n *\n * This allows CLI to:\n * 1. Call prepareUpgrade to build image, prepare release, get gas estimate\n * 2. Prompt user to confirm the cost\n * 3. Call executeUpgrade with confirmed gas params\n */\nexport async function prepareUpgrade(\n options: Omit<SDKUpgradeOptions, \"gas\"> & { skipTelemetry?: boolean },\n logger: Logger = defaultLogger,\n): Promise<PrepareUpgradeResult> {\n return withSDKTelemetry(\n {\n functionName: \"prepareUpgrade\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Do preflight checks (auth, network, etc.) first\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 2. Validate all required parameters upfront\n const appID = validateUpgradeOptions(options as SDKUpgradeOptions);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 3. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 4. Prepare the release (includes build/push if needed)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID as string,\n },\n logger,\n );\n\n // 5. Check current permission state and determine if change is needed\n logger.debug(\"Checking current log permission state...\");\n const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);\n const needsPermissionChange = currentlyPublic !== publicLogs;\n\n // 6. Prepare the upgrade batch (creates executions without sending)\n logger.debug(\"Preparing upgrade batch...\");\n const batch = await prepareUpgradeBatch({\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n release,\n publicLogs,\n needsPermissionChange,\n });\n\n // 7. Estimate gas for the batch\n logger.debug(\"Estimating gas...\");\n const gasEstimate = await estimateBatchGas({\n publicClient: batch.publicClient,\n environmentConfig: batch.environmentConfig,\n executions: batch.executions,\n });\n\n return {\n prepared: {\n batch,\n appId: appID as string,\n imageRef: finalImageRef,\n preflightCtx: {\n privateKey: preflightCtx.privateKey,\n rpcUrl: preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n },\n },\n gasEstimate,\n };\n },\n );\n}\n\n/**\n * Execute a prepared upgrade\n *\n * Call this after prepareUpgrade and user confirmation.\n * Note: This only submits the on-chain transaction. Call watchUpgrade separately\n * to wait for the upgrade to complete.\n */\nexport async function executeUpgrade(\n prepared: PreparedUpgrade,\n gas: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint } | undefined,\n logger: Logger = defaultLogger,\n skipTelemetry?: boolean,\n): Promise<UpgradeResult> {\n return withSDKTelemetry(\n {\n functionName: \"executeUpgrade\",\n skipTelemetry: skipTelemetry,\n },\n async () => {\n // Execute the batch transaction\n logger.info(\"Upgrading on-chain...\");\n const txHash = await executeUpgradeBatch(prepared.batch, gas, logger);\n\n return {\n appId: prepared.appId,\n imageRef: prepared.imageRef,\n txHash,\n };\n },\n );\n}\n\n/**\n * Watch an upgrade until it completes\n *\n * Call this after executeUpgrade to wait for the upgrade to finish.\n * Can be called separately to allow for intermediate operations.\n */\nexport async function watchUpgrade(\n appId: string,\n privateKey: string,\n rpcUrl: string,\n environment: string,\n logger: Logger = defaultLogger,\n clientId?: string,\n skipTelemetry?: boolean,\n): Promise<void> {\n return withSDKTelemetry(\n {\n functionName: \"watchUpgrade\",\n skipTelemetry: skipTelemetry,\n properties: {\n environment,\n },\n },\n async () => {\n const environmentConfig = getEnvironmentConfig(environment);\n\n logger.info(\"Waiting for upgrade to complete...\");\n await watchUntilUpgradeComplete(\n {\n privateKey,\n rpcUrl,\n environmentConfig,\n appId: appId as Address,\n clientId,\n },\n logger,\n );\n },\n );\n}\n","/**\n * Create command\n *\n * Creates a new app project from a template\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Logger } from \"../../../common/types\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport {\n fetchTemplateCatalog,\n getTemplate,\n getCategoryDescriptions,\n DEFAULT_TEMPLATE_REPO,\n DEFAULT_TEMPLATE_VERSION,\n ENV_VAR_USE_LOCAL_TEMPLATES,\n ENV_VAR_TEMPLATES_PATH,\n type TemplateEntry,\n} from \"../../../common/templates/catalog\";\nimport { fetchTemplate, fetchTemplateSubdirectory } from \"../../../common/templates/git\";\nimport { postProcessTemplate } from \"../../../common/templates/postprocess\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\n/**\n * Required create app options for SDK (non-interactive)\n */\nexport interface SDKCreateAppOpts {\n /** Project name - required */\n name: string;\n /** Programming language - required (typescript, golang, rust, python) */\n language: string;\n /** Template name/category (e.g., \"minimal\") or custom template URL - optional, defaults to first available */\n template?: string;\n /** Template version/ref - optional */\n templateVersion?: string;\n /** Verbose output - optional */\n verbose?: boolean;\n /** Skip telemetry (used when called from CLI) - optional */\n skipTelemetry?: boolean;\n}\n\n/**\n * Legacy interface for backward compatibility\n * @deprecated Use SDKCreateAppOpts instead\n */\nexport interface CreateAppOpts {\n name?: string;\n language?: string;\n template?: string;\n templateVersion?: string;\n verbose?: boolean;\n skipTelemetry?: boolean;\n}\n\n// Language configuration\nexport const PRIMARY_LANGUAGES = [\"typescript\", \"golang\", \"rust\", \"python\"];\n\nexport const LANGUAGE_FILES: Record<string, string[]> = {\n typescript: [\"package.json\"],\n rust: [\"Cargo.toml\", \"Dockerfile\"],\n golang: [\"go.mod\"],\n};\n\n/**\n * Project configuration\n */\ninterface ProjectConfig {\n name: string;\n language?: string;\n templateName?: string;\n templateEntry?: TemplateEntry;\n repoURL: string;\n ref: string;\n subPath: string;\n}\n\n/**\n * Validate project name\n */\nfunction validateProjectName(name: string): void {\n if (!name) {\n throw new Error(\"Project name is required\");\n }\n if (name.includes(\" \")) {\n throw new Error(\"Project name cannot contain spaces\");\n }\n}\n\n/**\n * Validate language\n */\nfunction validateLanguage(language: string): void {\n if (!language) {\n throw new Error(\"Language is required\");\n }\n\n if (!PRIMARY_LANGUAGES.includes(language)) {\n throw new Error(\n `Invalid language: ${language}. Must be one of: ${PRIMARY_LANGUAGES.join(\", \")}`,\n );\n }\n}\n\n/**\n * Check if a string is a URL\n */\nfunction isURL(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get available template categories for a language\n */\nexport async function getAvailableTemplates(\n language: string,\n): Promise<Array<{ name: string; description: string }>> {\n const catalog = await fetchTemplateCatalog();\n const categoryDescriptions = getCategoryDescriptions(catalog, language);\n\n if (Object.keys(categoryDescriptions).length === 0) {\n throw new Error(`No templates found for language ${language}`);\n }\n\n // Sort categories alphabetically for consistent ordering\n const categories = Object.keys(categoryDescriptions).sort();\n\n return categories.map((category) => ({\n name: category,\n description: categoryDescriptions[category] || \"\",\n }));\n}\n\n/**\n * Create a new app project from template\n *\n * This function is non-interactive and requires all parameters to be provided explicitly.\n *\n * @param options - Required options including name and language\n * @param logger - Optional logger instance\n * @throws Error if required parameters are missing or invalid\n */\nexport async function createApp(\n options: SDKCreateAppOpts | CreateAppOpts,\n logger: Logger = defaultLogger,\n): Promise<void> {\n return withSDKTelemetry(\n {\n functionName: \"createApp\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n language: options.language || \"\",\n },\n },\n async () => {\n // 1. Validate required parameters\n validateProjectName(options.name || \"\");\n validateLanguage(options.language || \"\");\n\n // 2. Gather project configuration\n const cfg = await gatherProjectConfig(\n {\n ...options,\n name: options.name!,\n language: options.language!,\n },\n logger,\n );\n\n // 3. Check if directory exists\n if (fs.existsSync(cfg.name)) {\n throw new Error(`Directory ${cfg.name} already exists`);\n }\n\n // 4. Create project directory\n fs.mkdirSync(cfg.name, { mode: 0o755 });\n\n try {\n // 5. Populate project from template\n await populateProjectFromTemplate(cfg, options, logger);\n\n // 6. Post-process template\n if (cfg.subPath && cfg.language && cfg.templateEntry) {\n await postProcessTemplate(cfg.name, cfg.language, cfg.templateEntry, logger);\n }\n\n logger.info(`Successfully created ${cfg.language || \"project\"} project: ${cfg.name}`);\n } catch (error: any) {\n // Cleanup on failure\n fs.rmSync(cfg.name, { recursive: true, force: true });\n throw error;\n }\n },\n );\n}\n\n/**\n * Gather project configuration (non-interactive)\n */\nasync function gatherProjectConfig(\n options: { name: string; language: string; template?: string; templateVersion?: string },\n logger: Logger,\n): Promise<ProjectConfig> {\n const cfg: ProjectConfig = {\n repoURL: DEFAULT_TEMPLATE_REPO,\n ref: DEFAULT_TEMPLATE_VERSION,\n subPath: \"\",\n name: options.name,\n };\n\n // Handle custom template repo (if template is a URL)\n const customTemplateRepo = options.template;\n if (customTemplateRepo && isURL(customTemplateRepo)) {\n cfg.repoURL = customTemplateRepo;\n cfg.ref = options.templateVersion || DEFAULT_TEMPLATE_VERSION;\n return cfg;\n }\n\n // Handle built-in templates\n cfg.language = options.language;\n\n // Get template name (category)\n let templateName = customTemplateRepo; // If provided and not a URL, it's a template name\n\n if (!templateName) {\n // Default to first available template for the language\n const availableTemplates = await getAvailableTemplates(options.language);\n if (availableTemplates.length === 0) {\n throw new Error(`No templates found for language ${options.language}`);\n }\n templateName = availableTemplates[0].name;\n logger.debug(`Using default template: ${templateName}`);\n }\n cfg.templateName = templateName;\n\n // Resolve template details from catalog\n const catalog = await fetchTemplateCatalog();\n const matchedTemplate = getTemplate(catalog, templateName, options.language);\n cfg.templateEntry = matchedTemplate;\n cfg.repoURL = DEFAULT_TEMPLATE_REPO;\n cfg.ref = options.templateVersion || DEFAULT_TEMPLATE_VERSION;\n cfg.subPath = matchedTemplate.path;\n\n return cfg;\n}\n\n/**\n * Populate project from template\n */\nasync function populateProjectFromTemplate(\n cfg: ProjectConfig,\n options: { verbose?: boolean },\n logger: Logger,\n): Promise<void> {\n // Handle local templates for development\n if (process.env[ENV_VAR_USE_LOCAL_TEMPLATES] === \"true\") {\n let eigenxTemplatesPath = process.env[ENV_VAR_TEMPLATES_PATH];\n if (!eigenxTemplatesPath) {\n // Look for eigenx-templates as a sibling directory\n const possiblePaths = [\"eigenx-templates\", \"../eigenx-templates\"];\n for (const possiblePath of possiblePaths) {\n const testPath = path.join(possiblePath, \"templates\");\n if (fs.existsSync(testPath)) {\n eigenxTemplatesPath = possiblePath;\n break;\n }\n }\n if (!eigenxTemplatesPath) {\n throw new Error(\n `Cannot find eigenx-templates directory. Set ${ENV_VAR_TEMPLATES_PATH} or ensure eigenx-templates is a sibling directory`,\n );\n }\n }\n\n const localTemplatePath = path.join(eigenxTemplatesPath, cfg.subPath);\n if (!fs.existsSync(localTemplatePath)) {\n throw new Error(`Local template not found at ${localTemplatePath}`);\n }\n\n await copyDirectory(localTemplatePath, cfg.name);\n logger.info(`Using local template from ${localTemplatePath}`);\n return;\n }\n\n // Fetch from remote repository\n if (cfg.subPath) {\n await fetchTemplateSubdirectory(cfg.repoURL, cfg.ref, cfg.subPath, cfg.name, logger);\n } else {\n await fetchTemplate(\n cfg.repoURL,\n cfg.ref,\n cfg.name,\n { verbose: options.verbose || false },\n logger,\n );\n }\n}\n\n/**\n * Copy directory recursively\n */\nasync function copyDirectory(src: string, dst: string): Promise<void> {\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const dstPath = path.join(dst, entry.name);\n\n if (entry.isDirectory()) {\n fs.mkdirSync(dstPath, { recursive: true });\n await copyDirectory(srcPath, dstPath);\n } else {\n const stat = fs.statSync(srcPath);\n fs.copyFileSync(srcPath, dstPath);\n fs.chmodSync(dstPath, stat.mode);\n }\n }\n}\n","/**\n * Template catalog system\n *\n * Fetches and manages template catalog from templates.json\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n// Environment variable names\nexport const ENV_VAR_USE_LOCAL_TEMPLATES = \"EIGENX_USE_LOCAL_TEMPLATES\";\nexport const ENV_VAR_TEMPLATES_PATH = \"EIGENX_TEMPLATES_PATH\";\n\n// Default repository URL for templates\nexport const DEFAULT_TEMPLATE_REPO = \"https://github.com/Layr-Labs/eigenx-templates\";\n\n// Default version/branch for templates\nexport const DEFAULT_TEMPLATE_VERSION = \"main\";\n\n// Default catalog URL in the eigenx-templates repository\nexport const DEFAULT_CATALOG_URL =\n \"https://raw.githubusercontent.com/Layr-Labs/eigenx-templates/main/templates.json\";\n\n// Cache duration for the catalog (15 minutes)\nexport const CATALOG_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds\n\n/**\n * TemplateEntry represents a single template in the catalog\n */\nexport interface TemplateEntry {\n path: string;\n description: string;\n postProcess?: {\n replaceNameIn?: string[];\n };\n}\n\n/**\n * TemplateCatalog represents the structure of templates.json\n * Organized by language first, then by category (e.g., \"typescript\" -> \"minimal\")\n */\nexport interface TemplateCatalog {\n [language: string]: {\n [category: string]: TemplateEntry;\n };\n}\n\n// In-memory cache\ninterface CatalogCache {\n catalog: TemplateCatalog | null;\n expiresAt: number;\n}\n\nlet cache: CatalogCache = {\n catalog: null,\n expiresAt: 0,\n};\n\n/**\n * Fetch template catalog from remote URL or local file\n * Uses a 15-minute in-memory cache to avoid excessive network requests\n */\nexport async function fetchTemplateCatalog(): Promise<TemplateCatalog> {\n // Check if using local templates\n if (process.env[ENV_VAR_USE_LOCAL_TEMPLATES] === \"true\") {\n return fetchLocalCatalog();\n }\n\n // Check cache first\n if (cache.catalog && Date.now() < cache.expiresAt) {\n return cache.catalog;\n }\n\n // Fetch from remote\n const catalog = await fetchRemoteCatalog(DEFAULT_CATALOG_URL);\n\n // Update cache\n cache.catalog = catalog;\n cache.expiresAt = Date.now() + CATALOG_CACHE_DURATION;\n\n return catalog;\n}\n\n/**\n * Fetch catalog from remote URL\n */\nasync function fetchRemoteCatalog(url: string): Promise<TemplateCatalog> {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(10000), // 10 second timeout\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch template catalog: HTTP ${response.status}`);\n }\n\n const data = await response.json();\n return data as TemplateCatalog;\n}\n\n/**\n * Fetch local catalog from templates.json file\n */\nfunction fetchLocalCatalog(): TemplateCatalog {\n // Look for EIGENX_TEMPLATES_PATH first\n let templatesPath = process.env[ENV_VAR_TEMPLATES_PATH];\n\n if (!templatesPath) {\n // Look for eigenx-templates directory as a sibling\n const cwd = process.cwd();\n const possiblePaths = [\n path.join(cwd, \"eigenx-templates\"),\n path.join(path.dirname(cwd), \"eigenx-templates\"),\n ];\n\n for (const possiblePath of possiblePaths) {\n if (fs.existsSync(possiblePath)) {\n templatesPath = possiblePath;\n break;\n }\n }\n\n if (!templatesPath) {\n throw new Error(\n \"Local templates directory not found. Set EIGENX_TEMPLATES_PATH or ensure eigenx-templates is a sibling directory\",\n );\n }\n }\n\n const catalogPath = path.join(templatesPath, \"templates.json\");\n if (!fs.existsSync(catalogPath)) {\n throw new Error(`Local template catalog not found at ${catalogPath}`);\n }\n\n const data = fs.readFileSync(catalogPath, \"utf-8\");\n return JSON.parse(data) as TemplateCatalog;\n}\n\n/**\n * Get template entry by language and category\n */\nexport function getTemplate(\n catalog: TemplateCatalog,\n category: string,\n language: string,\n): TemplateEntry {\n const templates = catalog[language];\n if (!templates) {\n throw new Error(`Language \"${language}\" not found in catalog`);\n }\n\n const template = templates[category];\n if (!template) {\n throw new Error(`Category \"${category}\" not found for language \"${language}\"`);\n }\n\n return template;\n}\n\n/**\n * Get category descriptions for a given language\n */\nexport function getCategoryDescriptions(\n catalog: TemplateCatalog,\n language: string,\n): Record<string, string> {\n const templates = catalog[language];\n if (!templates) {\n return {};\n }\n\n const descriptions: Record<string, string> = {};\n for (const [category, template] of Object.entries(templates)) {\n descriptions[category] = template.description || \"\";\n }\n\n return descriptions;\n}\n","/**\n * Git template fetching\n *\n * Fetches templates from Git repositories\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { exec, execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport { Logger } from \"../types\";\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\nexport interface GitFetcherConfig {\n verbose: boolean;\n}\n\n/**\n * Fetch full template repository\n */\nexport async function fetchTemplate(\n repoURL: string,\n ref: string,\n targetDir: string,\n config: GitFetcherConfig,\n logger: Logger,\n): Promise<void> {\n if (!repoURL) {\n throw new Error(\"repoURL is required\");\n }\n\n logger.info(`\\nCloning repo: ${repoURL} → ${targetDir}\\n`);\n\n try {\n // Clone with no checkout\n await execAsync(`git clone --no-checkout --progress ${repoURL} ${targetDir}`, {\n maxBuffer: 10 * 1024 * 1024,\n });\n\n // Checkout the desired ref\n await execFileAsync(\"git\", [\"-C\", targetDir, \"checkout\", \"--quiet\", ref], {\n maxBuffer: 10 * 1024 * 1024,\n });\n\n // Update submodules\n await execFileAsync(\n \"git\",\n [\"-C\", targetDir, \"submodule\", \"update\", \"--init\", \"--recursive\", \"--progress\"],\n { maxBuffer: 10 * 1024 * 1024 },\n );\n\n logger.info(`Clone repo complete: ${repoURL}\\n`);\n } catch (error: any) {\n throw new Error(`Failed to clone repository: ${error.message}`);\n }\n}\n\n/**\n * Fetch subdirectory from template repository using sparse checkout\n */\nexport async function fetchTemplateSubdirectory(\n repoURL: string,\n ref: string,\n subPath: string,\n targetDir: string,\n logger: Logger,\n): Promise<void> {\n if (!repoURL) {\n throw new Error(\"repoURL is required\");\n }\n if (!subPath) {\n throw new Error(\"subPath is required\");\n }\n\n // Create temporary directory for sparse clone\n let tempDir: string;\n try {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"eigenx-template-\"));\n } catch {\n // If that fails, try ~/.eigenx/tmp\n const homeDir = os.homedir();\n const fallbackBase = path.join(homeDir, \".eigenx\", \"tmp\");\n fs.mkdirSync(fallbackBase, { recursive: true });\n tempDir = fs.mkdtempSync(path.join(fallbackBase, \"eigenx-template-\"));\n }\n\n try {\n logger.info(`\\nCloning template: ${repoURL} → extracting ${subPath}\\n`);\n\n // Clone with sparse checkout\n await cloneSparse(repoURL, ref, subPath, tempDir);\n\n // Verify subdirectory exists\n const srcPath = path.join(tempDir, subPath);\n if (!fs.existsSync(srcPath)) {\n throw new Error(`Template subdirectory ${subPath} not found in ${repoURL}`);\n }\n\n // Copy subdirectory contents to target\n await copyDirectory(srcPath, targetDir);\n\n logger.info(`Template extraction complete: ${subPath}\\n`);\n } finally {\n // Cleanup temp directory\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Clone repository with sparse checkout\n */\nasync function cloneSparse(\n repoURL: string,\n ref: string,\n subPath: string,\n tempDir: string,\n // config: GitFetcherConfig\n): Promise<void> {\n try {\n // Initialize git repository\n await execFileAsync(\"git\", [\"init\", tempDir]);\n\n // Add remote\n await execFileAsync(\"git\", [\"-C\", tempDir, \"remote\", \"add\", \"origin\", repoURL]);\n\n // Enable sparse checkout\n await execFileAsync(\"git\", [\"-C\", tempDir, \"config\", \"core.sparseCheckout\", \"true\"]);\n\n // Set sparse checkout path\n const sparseCheckoutPath = path.join(tempDir, \".git/info/sparse-checkout\");\n fs.writeFileSync(sparseCheckoutPath, `${subPath}\\n`);\n\n // Fetch and checkout\n await execFileAsync(\"git\", [\"-C\", tempDir, \"fetch\", \"origin\", ref]);\n\n await execFileAsync(\"git\", [\"-C\", tempDir, \"checkout\", ref]);\n } catch (error: any) {\n throw new Error(`Failed to clone sparse repository: ${error.message}`);\n }\n}\n\n/**\n * Copy directory recursively\n */\nasync function copyDirectory(src: string, dst: string): Promise<void> {\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const dstPath = path.join(dst, entry.name);\n\n if (entry.isDirectory()) {\n fs.mkdirSync(dstPath, { recursive: true });\n await copyDirectory(srcPath, dstPath);\n } else {\n const stat = fs.statSync(srcPath);\n fs.copyFileSync(srcPath, dstPath);\n fs.chmodSync(dstPath, stat.mode);\n }\n }\n}\n","/**\n * Template post-processing\n *\n * Updates template files with project-specific values\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Logger } from \"../types\";\nimport { TemplateEntry } from \"./catalog\";\nimport { getDirname } from \"../utils/dirname\";\n\n// Config file paths\nconst __dirname = getDirname();\nconst CONFIG_DIR = path.join(__dirname, \"../../config\");\n\n/**\n * Post-process template files\n */\nexport async function postProcessTemplate(\n projectDir: string,\n language: string,\n templateEntry: TemplateEntry,\n logger: Logger,\n): Promise<void> {\n const projectName = path.basename(projectDir);\n const templateName = `eigenx-tee-${language}-app`;\n\n // 1. Copy .gitignore\n await copyGitignore(projectDir);\n\n // 2. Copy shared template files (.env.example, README.md)\n await copySharedTemplateFiles(projectDir);\n\n // 3. Get files to update from template metadata, fallback to just README.md\n const filesToUpdate = templateEntry.postProcess?.replaceNameIn || [\"README.md\"];\n\n // 4. Update all files specified in template metadata\n for (const filename of filesToUpdate) {\n await updateProjectFile(projectDir, filename, templateName, projectName, logger);\n }\n}\n\n/**\n * Copy .gitignore from config\n */\nasync function copyGitignore(projectDir: string): Promise<void> {\n const destPath = path.join(projectDir, \".gitignore\");\n\n // Check if .gitignore already exists\n if (fs.existsSync(destPath)) {\n return; // File already exists, skip copying\n }\n\n // Load from config directory\n const gitignorePath = path.join(CONFIG_DIR, \".gitignore\");\n if (fs.existsSync(gitignorePath)) {\n fs.copyFileSync(gitignorePath, destPath);\n } else {\n // Fallback to default gitignore content\n const defaultGitignore = `# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Build outputs\n/bin/\n/out/\n\n# OS-specific files\n.DS_Store\nThumbs.db\n\n# Editor and IDE files\n.vscode/\n.idea/\n*.swp\n\n# Environment\n.env\n\n# Language-specific build outputs\nnode_modules/\ndist/\nbuild/\ntarget/\n__pycache__/\n*.pyc\n`;\n fs.writeFileSync(destPath, defaultGitignore, { mode: 0o644 });\n }\n}\n\n/**\n * Copy shared template files\n */\nasync function copySharedTemplateFiles(projectDir: string): Promise<void> {\n // Write .env.example\n const envPath = path.join(projectDir, \".env.example\");\n const envExamplePath = path.join(CONFIG_DIR, \".env.example\");\n if (fs.existsSync(envExamplePath)) {\n fs.copyFileSync(envExamplePath, envPath);\n } else {\n // Fallback to default .env.example\n const defaultEnvExample = `# Environment variables\n# Variables ending with _PUBLIC will be visible on-chain\n# All other variables will be encrypted\n\n# Example public variable\n# API_URL_PUBLIC=https://api.example.com\n\n# Example private variable\n# SECRET_KEY=your-secret-key-here\n`;\n fs.writeFileSync(envPath, defaultEnvExample, { mode: 0o644 });\n }\n\n // Write or append README.md\n const readmePath = path.join(projectDir, \"README.md\");\n const readmeConfigPath = path.join(CONFIG_DIR, \"README.md\");\n\n if (fs.existsSync(readmePath)) {\n // README.md exists, append the content\n const readmeContent = fs.existsSync(readmeConfigPath)\n ? fs.readFileSync(readmeConfigPath, \"utf-8\")\n : getDefaultReadme();\n fs.appendFileSync(readmePath, \"\\n\" + readmeContent);\n } else {\n // README.md doesn't exist, create it\n const readmeContent = fs.existsSync(readmeConfigPath)\n ? fs.readFileSync(readmeConfigPath, \"utf-8\")\n : getDefaultReadme();\n fs.writeFileSync(readmePath, readmeContent, { mode: 0o644 });\n }\n}\n\n/**\n * Get default README content\n */\nfunction getDefaultReadme(): string {\n return `## Prerequisites\n\nBefore deploying, you'll need:\n\n- **Docker** - To package and publish your application image\n- **ETH** - To pay for deployment transactions\n\n## Deployment\n\n\\`\\`\\`bash\necloud compute app deploy username/image-name\n\\`\\`\\`\n\nThe CLI will automatically detect the \\`Dockerfile\\` and build your app before deploying.\n\n## Management & Monitoring\n\n\\`\\`\\`bash\necloud compute app list # List all apps\necloud compute app info [app-name] # Get app details\necloud compute app logs [app-name] # View logs\necloud compute app start [app-name] # Start stopped app\necloud compute app stop [app-name] # Stop running app\necloud compute app terminate [app-name] # Terminate app\necloud compute app upgrade [app-name] [image] # Update deployment\n\\`\\`\\`\n`;\n}\n\n/**\n * Update project file by replacing template name with project name\n */\nasync function updateProjectFile(\n projectDir: string,\n filename: string,\n oldString: string,\n newString: string,\n logger: Logger,\n): Promise<void> {\n const filePath = path.join(projectDir, filename);\n\n // Check if file exists\n if (!fs.existsSync(filePath)) {\n logger.debug(`File ${filename} not found, skipping update`);\n return;\n }\n\n // Read current file\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n // Replace the specified string\n const newContent = content.replaceAll(oldString, newString);\n\n // Write back to file\n fs.writeFileSync(filePath, newContent, { mode: 0o644 });\n}\n","/**\n * Logs command\n *\n * View app logs with optional watch mode\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport { Address } from \"viem\";\nimport { Logger } from \"../../../common/types\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport { UserApiClient } from \"../../../common/utils/userapi\";\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport { validateAppID } from \"../../../common/utils/validation\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\nimport chalk from \"chalk\";\n\n/**\n * Required logs options for SDK (non-interactive)\n */\nexport interface SDKLogsOptions {\n /** App ID (address) or app name - required */\n appID: string | Address;\n /** Watch logs continuously - optional */\n watch?: boolean;\n /** Environment name - optional, defaults to 'sepolia' */\n environment?: string;\n /** Private key for authenticated requests - optional */\n privateKey?: string;\n /** RPC URL - optional, uses environment default */\n rpcUrl?: string;\n /** Client ID for API requests - optional */\n clientId?: string;\n /** Skip telemetry (for CLI usage) - optional */\n skipTelemetry?: boolean;\n}\n\n/**\n * Legacy interface for backward compatibility\n * @deprecated Use SDKLogsOptions instead\n */\nexport interface LogsOptions {\n appID?: string | Address;\n watch?: boolean;\n environment?: string;\n privateKey?: string;\n rpcUrl?: string;\n clientId?: string;\n}\n\n// App status constants\nconst AppStatusCreated = \"Created\";\nconst AppStatusDeploying = \"Deploying\";\nconst AppStatusUpgrading = \"Upgrading\";\nconst AppStatusResuming = \"Resuming\";\nconst AppStatusStopping = \"Stopping\";\nconst AppStatusStopped = \"Stopped\";\nconst AppStatusTerminating = \"Terminating\";\nconst AppStatusTerminated = \"Terminated\";\nconst AppStatusSuspended = \"Suspended\";\nconst AppStatusFailed = \"Failed\";\n\n// Watch poll interval\nconst WATCH_POLL_INTERVAL_SECONDS = 5;\n\n/**\n * Format app display\n */\nfunction formatAppDisplay(environmentName: string, appID: Address, profileName: string): string {\n if (profileName) {\n return `${profileName} (${environmentName}:${appID})`;\n }\n return `${environmentName}:${appID}`;\n}\n\n/**\n * Show countdown for watch mode\n * Shows countdown from seconds down to 0, one second at a time\n */\nasync function showCountdown(seconds: number, shouldStop: () => boolean): Promise<void> {\n for (let i = seconds; i >= 0; i--) {\n if (shouldStop()) {\n return;\n }\n process.stdout.write(chalk.gray(`\\rRefreshing in ${i}...`));\n if (i > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n}\n\n/**\n * Watch logs continuously\n */\nasync function watchLogs(\n appID: Address,\n userApiClient: UserApiClient,\n initialLogs: string,\n): Promise<void> {\n const tailSize = 65536; // 64KB\n\n // Track previously seen logs\n let prevLogs = initialLogs;\n\n // Handle graceful shutdown\n let shouldStop = false;\n const stopHandler = () => {\n shouldStop = true;\n };\n process.on(\"SIGINT\", stopHandler);\n process.on(\"SIGTERM\", stopHandler);\n\n try {\n while (!shouldStop) {\n // Show countdown\n await showCountdown(WATCH_POLL_INTERVAL_SECONDS, () => shouldStop);\n\n if (shouldStop) {\n break;\n }\n\n // Fetch fresh logs\n let newLogs: string;\n try {\n newLogs = await userApiClient.getLogs(appID);\n } catch {\n // Silently continue on error in watch mode\n continue;\n }\n\n // Skip if no new logs\n if (newLogs === prevLogs) {\n continue;\n }\n\n // Clear the countdown line\n process.stdout.write(\"\\r\\x1b[K\");\n\n if (newLogs.startsWith(prevLogs)) {\n // Normal append - show only new content\n const newContent = newLogs.slice(prevLogs.length);\n process.stdout.write(newContent);\n } else {\n // Check if logs were truncated (old tail matches somewhere in new)\n const tail = prevLogs.slice(Math.max(0, prevLogs.length - tailSize)); // Last 64KB\n const idx = newLogs.lastIndexOf(tail);\n if (idx !== -1) {\n // Found the tail at position idx\n // Print everything after where the old logs ended\n process.stdout.write(newLogs.slice(idx + tail.length));\n } else {\n if (newLogs.length < prevLogs.length) {\n console.log(\"--- Logs restarted ---\");\n } else {\n console.log(\"--- Log stream gap detected ---\");\n }\n process.stdout.write(newLogs);\n }\n }\n // Reset any incomplete formatting/special chars and add blank line\n process.stdout.write(\"\\x1b[0m\");\n console.log();\n prevLogs = newLogs;\n }\n } finally {\n process.removeListener(\"SIGINT\", stopHandler);\n process.removeListener(\"SIGTERM\", stopHandler);\n }\n\n console.log(\"\\nStopped watching\");\n}\n\n/**\n * View app logs\n *\n * This function is non-interactive and requires appID to be provided explicitly.\n *\n * @param options - Required options including appID\n * @param logger - Optional logger instance\n * @throws Error if appID is missing or invalid\n */\nexport async function logs(\n options: SDKLogsOptions | LogsOptions,\n logger: Logger = defaultLogger,\n skipTelemetry: boolean = false,\n): Promise<void> {\n const skipTelemetryFlag = skipTelemetry || (options as SDKLogsOptions).skipTelemetry || false;\n\n return withSDKTelemetry(\n {\n functionName: \"logs\",\n skipTelemetry: skipTelemetryFlag,\n properties: { environment: (options.environment || \"sepolia\") as string },\n },\n async () => {\n console.log();\n\n // Validate required parameters\n if (!options.appID) {\n throw new Error(\"appID is required for viewing logs\");\n }\n\n // Get environment config\n const environment = options.environment || \"sepolia\";\n const environmentConfig = getEnvironmentConfig(environment);\n\n // Get RPC URL (needed for contract queries and authentication)\n const rpcUrl = options.rpcUrl || environmentConfig.defaultRPCURL;\n if (!rpcUrl) {\n throw new Error(\"RPC URL is required for authenticated requests\");\n }\n\n // Validate app ID (must be a valid address - name resolution is done by CLI)\n const appID = validateAppID(options.appID);\n\n // Format app display (no profile name in SDK - CLI handles that)\n const formattedApp = formatAppDisplay(environmentConfig.name, appID, \"\");\n\n // Create user API client\n const userApiClient = new UserApiClient(\n environmentConfig,\n options.privateKey,\n rpcUrl,\n options.clientId,\n );\n\n // Fetch logs\n let logsText: string;\n let logsError: Error | null = null;\n try {\n logsText = await userApiClient.getLogs(appID);\n } catch (err: any) {\n logsError = err;\n logsText = \"\";\n }\n\n const watchMode = options.watch || false;\n\n // Handle empty logs or errors\n if (logsError || logsText.trim() === \"\") {\n // If watch mode is enabled, enter watch loop even without initial logs\n if (watchMode) {\n logger.info(\"\\nWaiting for logs to become available...\");\n console.log();\n await watchLogs(appID, userApiClient, \"\");\n return;\n }\n\n // Not watch mode - check app status to provide helpful message and exit\n try {\n const statuses = await userApiClient.getStatuses([appID]);\n if (statuses.length > 0) {\n const status = statuses[0].status;\n switch (status) {\n case AppStatusCreated:\n case AppStatusDeploying:\n logger.info(\n `${formattedApp} is currently being provisioned. Logs will be available once deployment is complete.`,\n );\n return;\n case AppStatusUpgrading:\n logger.info(\n `${formattedApp} is currently upgrading. Logs will be available once upgrade is complete.`,\n );\n return;\n case AppStatusResuming:\n logger.info(\n `${formattedApp} is currently resuming. Logs will be available shortly.`,\n );\n return;\n case AppStatusStopping:\n logger.info(`${formattedApp} is currently stopping. Logs may be limited.`);\n return;\n case AppStatusStopped:\n case AppStatusTerminating:\n case AppStatusTerminated:\n case AppStatusSuspended:\n logger.info(`${formattedApp} is ${status.toLowerCase()}. Logs are not available.`);\n return;\n case AppStatusFailed:\n logger.info(\n `${formattedApp} has failed. Check the app status for more information.`,\n );\n return;\n }\n }\n } catch {\n // If we can't get status either, continue to error handling\n }\n\n // If we can't get status either, return the original logs error\n if (logsError) {\n throw new Error(\n `Failed to get logs, you can watch for logs by calling this command with the --watch flag (or --w): ${logsError.message}`,\n );\n }\n throw new Error(\n \"Failed to get logs, you can watch for logs by calling this command with the --watch flag (or --w): empty logs\",\n );\n }\n\n // Print initial logs\n console.log(logsText);\n\n // Check if watch mode is enabled\n if (!watchMode) {\n return;\n }\n\n // Watch mode: continuously fetch and display new logs\n await watchLogs(appID, userApiClient, logsText);\n },\n );\n}\n","/**\n * Main Compute namespace entry point\n */\n\nimport { createAppModule, type AppModule, type AppModuleConfig } from \"./app\";\n\nexport interface ComputeModule {\n app: AppModule;\n}\n\nexport interface ComputeModuleConfig {\n verbose?: boolean;\n privateKey: `0x${string}`;\n rpcUrl: string;\n environment: string;\n clientId?: string;\n skipTelemetry?: boolean;\n}\n\nexport function createComputeModule(config: ComputeModuleConfig): ComputeModule {\n return {\n app: createAppModule(config),\n };\n}\n\n// Re-export app module for standalone use\nexport { createAppModule, type AppModule, type AppModuleConfig } from \"./app\";\n\n// Re-export app module utilities\nexport { encodeStartAppData, encodeStopAppData, encodeTerminateAppData } from \"./app\";\n"],"mappings":"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","names":["import_viem","exec","resolve","process","path","platform","resolve","err","child_process","import_util","resolve","process","Handlebars","import_handlebars","Handlebars","kms_encryption_public_key_default","kms_signing_public_key_default","kms_encryption_public_key_default","kms_signing_public_key_default","kms_encryption_public_key_default","kms_signing_public_key_default","__dirname","Docker","child_process","import_util","platform","fs","resolve","import_accounts","isDelegated","import_viem","import_accounts","import_viem","import_viem","import_viem","import_chains","FormData","fs","path","axios","resolve","import_viem","fs","import_viem","import_accounts","os","import_viem","CanViewAppLogsPermission","fs","path","fs","path","fs","path","os","import_child_process","import_util","execAsync","execFileAsync","fs","path","__dirname","copyDirectory","WATCH_POLL_INTERVAL_SECONDS","chalk","resolve"]}
|
|
1
|
+
{"version":3,"sources":["../src/compute.ts","../src/client/modules/compute/app/index.ts","../src/client/common/config/environment.ts","../src/client/common/docker/build.ts","../src/client/common/constants.ts","../src/client/common/docker/layer.ts","../src/client/common/docker/inspect.ts","../src/client/common/docker/push.ts","../src/client/common/templates/dockerfileTemplate.ts","../src/client/common/templates/Dockerfile.layered.tmpl","../src/client/common/templates/scriptTemplate.ts","../src/client/common/templates/compute-source-env.sh.tmpl","../keys/mainnet-alpha/prod/kms-encryption-public-key.pem","../keys/mainnet-alpha/prod/kms-signing-public-key.pem","../keys/sepolia/dev/kms-encryption-public-key.pem","../keys/sepolia/dev/kms-signing-public-key.pem","../keys/sepolia/prod/kms-encryption-public-key.pem","../keys/sepolia/prod/kms-signing-public-key.pem","../src/client/common/utils/keys.ts","../src/client/common/utils/dirname.ts","../src/client/common/registry/digest.ts","../src/client/common/encryption/kms.ts","../src/client/common/env/parser.ts","../src/client/common/release/prepare.ts","../src/client/common/contract/caller.ts","../src/client/common/contract/eip7702.ts","../src/client/common/abis/ERC7702Delegator.json","../src/client/common/utils/logger.ts","../src/client/common/utils/userapi.ts","../src/client/common/utils/auth.ts","../src/client/common/utils/helpers.ts","../src/client/common/abis/AppController.json","../src/client/common/abis/PermissionController.json","../src/client/common/contract/watcher.ts","../src/client/common/utils/validation.ts","../src/client/common/utils/preflight.ts","../src/client/common/telemetry/noop.ts","../src/client/common/telemetry/posthog.ts","../src/client/common/telemetry/index.ts","../src/client/common/telemetry/metricsContext.ts","../src/client/common/telemetry/wrapper.ts","../src/client/modules/compute/app/deploy.ts","../src/client/common/utils/permissions.ts","../src/client/modules/compute/app/upgrade.ts","../src/client/modules/compute/app/create.ts","../src/client/common/templates/catalog.ts","../src/client/common/templates/git.ts","../src/client/common/templates/postprocess.ts","../src/client/modules/compute/app/logs.ts","../src/client/modules/compute/index.ts"],"sourcesContent":["/**\n * Compute module entry point\n *\n * Import from \"@layr-labs/ecloud-sdk/compute\" for direct access to compute/app modules\n */\n\nexport * from \"./client/modules/compute\";\n","/**\n * Main App namespace entry point\n */\n\nimport {\n parseAbi,\n encodeFunctionData,\n Hex,\n createWalletClient,\n createPublicClient,\n http,\n} from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport {\n deploy as deployApp,\n prepareDeploy as prepareDeployFn,\n executeDeploy as executeDeployFn,\n watchDeployment as watchDeploymentFn,\n} from \"./deploy\";\nimport {\n upgrade as upgradeApp,\n prepareUpgrade as prepareUpgradeFn,\n executeUpgrade as executeUpgradeFn,\n watchUpgrade as watchUpgradeFn,\n} from \"./upgrade\";\nimport { createApp, CreateAppOpts } from \"./create\";\nimport { logs, LogsOptions } from \"./logs\";\n\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport {\n sendAndWaitForTransaction,\n undelegate,\n isDelegated,\n type GasEstimate,\n} from \"../../../common/contract/caller\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\nimport { UserApiClient } from \"../../../common/utils/userapi\";\n\nimport type {\n AppId,\n DeployAppOpts,\n LifecycleOpts,\n UpgradeAppOpts,\n AppProfile,\n AppProfileResponse,\n ExecuteDeployResult,\n ExecuteUpgradeResult,\n GasOpts,\n PrepareDeployOpts,\n PrepareUpgradeOpts,\n PreparedDeploy,\n PreparedUpgrade,\n} from \"../../../common/types\";\nimport { getLogger, addHexPrefix, getChainFromID } from \"../../../common/utils\";\n\n// Minimal ABI\nconst CONTROLLER_ABI = parseAbi([\n \"function startApp(address appId)\",\n \"function stopApp(address appId)\",\n \"function terminateApp(address appId)\",\n]);\n\n/**\n * Encode start app call data for gas estimation\n */\nexport function encodeStartAppData(appId: AppId): Hex {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"startApp\",\n args: [appId],\n });\n}\n\n/**\n * Encode stop app call data for gas estimation\n */\nexport function encodeStopAppData(appId: AppId): Hex {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"stopApp\",\n args: [appId],\n });\n}\n\n/**\n * Encode terminate app call data for gas estimation\n */\nexport function encodeTerminateAppData(appId: AppId): Hex {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"terminateApp\",\n args: [appId],\n });\n}\n\nexport interface AppModule {\n // Project creation\n create: (opts: CreateAppOpts) => Promise<void>;\n\n // Full deploy/upgrade\n deploy: (opts: DeployAppOpts) => Promise<{\n appId: AppId;\n tx: Hex;\n appName: string;\n imageRef: string;\n ipAddress?: string;\n }>;\n upgrade: (\n appId: AppId,\n opts: UpgradeAppOpts,\n ) => Promise<{ tx: Hex; appId: AppId; imageRef: string }>;\n\n // Granular deploy control\n prepareDeploy: (opts: PrepareDeployOpts) => Promise<{\n prepared: PreparedDeploy;\n gasEstimate: GasEstimate;\n }>;\n executeDeploy: (prepared: PreparedDeploy, gas?: GasOpts) => Promise<ExecuteDeployResult>;\n watchDeployment: (appId: AppId) => Promise<string | undefined>;\n\n // Granular upgrade control\n prepareUpgrade: (\n appId: AppId,\n opts: PrepareUpgradeOpts,\n ) => Promise<{\n prepared: PreparedUpgrade;\n gasEstimate: GasEstimate;\n }>;\n executeUpgrade: (prepared: PreparedUpgrade, gas?: GasOpts) => Promise<ExecuteUpgradeResult>;\n watchUpgrade: (appId: AppId) => Promise<void>;\n\n // Profile management\n setProfile: (appId: AppId, profile: AppProfile) => Promise<AppProfileResponse>;\n\n // Logs\n logs: (opts: LogsOptions) => Promise<void>;\n\n // Lifecycle\n start: (appId: AppId, opts?: LifecycleOpts) => Promise<{ tx: Hex | false }>;\n stop: (appId: AppId, opts?: LifecycleOpts) => Promise<{ tx: Hex | false }>;\n terminate: (appId: AppId, opts?: LifecycleOpts) => Promise<{ tx: Hex | false }>;\n\n // Delegation\n isDelegated: () => Promise<boolean>;\n undelegate: () => Promise<{ tx: Hex | false }>;\n}\n\nexport interface AppModuleConfig {\n verbose?: boolean;\n privateKey: Hex;\n rpcUrl: string;\n environment: string;\n clientId?: string;\n skipTelemetry?: boolean; // Skip telemetry when called from CLI\n}\n\nexport function createAppModule(ctx: AppModuleConfig): AppModule {\n const privateKey = addHexPrefix(ctx.privateKey);\n const skipTelemetry = ctx.skipTelemetry || false;\n\n // Pull config for selected Environment\n const environment = getEnvironmentConfig(ctx.environment);\n\n // Get logger that respects verbose setting\n const logger = getLogger(ctx.verbose);\n\n return {\n async create(opts) {\n return createApp(opts, logger);\n },\n // Write operations\n async deploy(opts) {\n // Map DeployAppOpts to SDKDeployOptions and call the deploy function\n const result = await deployApp(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environment: ctx.environment,\n appName: opts.name,\n instanceType: opts.instanceType,\n dockerfilePath: opts.dockerfile,\n envFilePath: opts.envFile,\n imageRef: opts.imageRef,\n logVisibility: opts.logVisibility,\n gas: opts.gas,\n },\n logger,\n );\n\n return {\n appId: result.appId as AppId,\n tx: result.txHash,\n ipAddress: result.ipAddress,\n appName: result.appName,\n imageRef: result.imageRef,\n };\n },\n\n async upgrade(appId, opts) {\n // Map UpgradeAppOpts to SDKUpgradeOptions and call the upgrade function\n const result = await upgradeApp(\n {\n appId: appId,\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environment: ctx.environment,\n instanceType: opts.instanceType,\n dockerfilePath: opts.dockerfile,\n envFilePath: opts.envFile,\n imageRef: opts.imageRef,\n logVisibility: opts.logVisibility,\n gas: opts.gas,\n },\n logger,\n );\n\n return {\n tx: result.txHash,\n appId: result.appId,\n imageRef: result.imageRef,\n };\n },\n\n // Granular deploy control\n async prepareDeploy(opts) {\n return prepareDeployFn(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environment: ctx.environment,\n appName: opts.name,\n instanceType: opts.instanceType,\n dockerfilePath: opts.dockerfile,\n envFilePath: opts.envFile,\n imageRef: opts.imageRef,\n logVisibility: opts.logVisibility,\n resourceUsageMonitoring: opts.resourceUsageMonitoring,\n skipTelemetry,\n },\n logger,\n );\n },\n\n async executeDeploy(prepared, gas) {\n // Create clients from module context\n const account = privateKeyToAccount(privateKey);\n const chain = getChainFromID(environment.chainID);\n const publicClient = createPublicClient({\n chain,\n transport: http(ctx.rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(ctx.rpcUrl),\n });\n\n const result = await executeDeployFn({\n prepared,\n context: {\n walletClient,\n publicClient,\n environmentConfig: environment,\n },\n gas,\n logger,\n skipTelemetry,\n });\n return {\n appId: result.appId,\n txHash: result.txHash,\n appName: result.appName,\n imageRef: result.imageRef,\n };\n },\n\n async watchDeployment(appId) {\n return watchDeploymentFn(\n appId,\n privateKey,\n ctx.rpcUrl,\n ctx.environment,\n logger,\n ctx.clientId,\n skipTelemetry,\n );\n },\n\n // Granular upgrade control\n async prepareUpgrade(appId, opts) {\n return prepareUpgradeFn(\n {\n appId,\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environment: ctx.environment,\n instanceType: opts.instanceType,\n dockerfilePath: opts.dockerfile,\n envFilePath: opts.envFile,\n imageRef: opts.imageRef,\n logVisibility: opts.logVisibility,\n resourceUsageMonitoring: opts.resourceUsageMonitoring,\n skipTelemetry,\n },\n logger,\n );\n },\n\n async executeUpgrade(prepared, gas) {\n // Create clients from module context\n const account = privateKeyToAccount(privateKey);\n const chain = getChainFromID(environment.chainID);\n const publicClient = createPublicClient({\n chain,\n transport: http(ctx.rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(ctx.rpcUrl),\n });\n\n const result = await executeUpgradeFn({\n prepared,\n context: {\n walletClient,\n publicClient,\n environmentConfig: environment,\n },\n gas,\n logger,\n skipTelemetry,\n });\n return {\n appId: result.appId,\n txHash: result.txHash,\n imageRef: result.imageRef,\n };\n },\n\n async watchUpgrade(appId) {\n return watchUpgradeFn(\n appId,\n privateKey,\n ctx.rpcUrl,\n ctx.environment,\n logger,\n ctx.clientId,\n skipTelemetry,\n );\n },\n\n // Profile management\n async setProfile(appId, profile) {\n return withSDKTelemetry(\n {\n functionName: \"setProfile\",\n skipTelemetry,\n properties: { environment: ctx.environment },\n },\n async () => {\n const userApiClient = new UserApiClient(\n environment,\n privateKey,\n ctx.rpcUrl,\n ctx.clientId,\n );\n return userApiClient.uploadAppProfile(\n appId,\n profile.name,\n profile.website,\n profile.description,\n profile.xURL,\n profile.imagePath,\n );\n },\n );\n },\n\n async logs(opts) {\n return logs(\n {\n privateKey,\n appID: opts.appID,\n watch: opts.watch,\n environment: ctx.environment,\n clientId: ctx.clientId,\n },\n logger,\n skipTelemetry, // Skip if called from CLI\n );\n },\n\n async start(appId, opts) {\n return withSDKTelemetry(\n {\n functionName: \"start\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n const pendingMessage = `Starting app ${appId}...`;\n\n const data = encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"startApp\",\n args: [appId],\n });\n\n const tx = await sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n to: environment.appControllerAddress,\n data,\n pendingMessage,\n txDescription: \"StartApp\",\n gas: opts?.gas,\n },\n logger,\n );\n return { tx };\n },\n );\n },\n\n async stop(appId, opts) {\n return withSDKTelemetry(\n {\n functionName: \"stop\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n const pendingMessage = `Stopping app ${appId}...`;\n\n const data = encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"stopApp\",\n args: [appId],\n });\n\n const tx = await sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n to: environment.appControllerAddress,\n data,\n pendingMessage,\n txDescription: \"StopApp\",\n gas: opts?.gas,\n },\n logger,\n );\n return { tx };\n },\n );\n },\n\n async terminate(appId, opts) {\n return withSDKTelemetry(\n {\n functionName: \"terminate\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n const pendingMessage = `Terminating app ${appId}...`;\n\n const data = encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"terminateApp\",\n args: [appId],\n });\n\n const tx = await sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n to: environment.appControllerAddress,\n data,\n pendingMessage,\n txDescription: \"TerminateApp\",\n gas: opts?.gas,\n },\n logger,\n );\n return { tx };\n },\n );\n },\n\n async isDelegated() {\n return isDelegated({\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n });\n },\n\n async undelegate() {\n return withSDKTelemetry(\n {\n functionName: \"undelegate\",\n skipTelemetry: skipTelemetry, // Skip if called from CLI\n properties: { environment: ctx.environment },\n },\n async () => {\n // perform the undelegate EIP7702 tx (sets delegated to zero address)\n const tx = await undelegate(\n {\n privateKey,\n rpcUrl: ctx.rpcUrl,\n environmentConfig: environment,\n },\n logger,\n );\n\n return { tx };\n },\n );\n },\n };\n}\n","/**\n * Environment configuration for different networks\n */\n\nimport { BillingEnvironmentConfig, EnvironmentConfig } from \"../types\";\n\n// Chain IDs\nexport const SEPOLIA_CHAIN_ID = 11155111;\nexport const MAINNET_CHAIN_ID = 1;\n\n// Common addresses across all chains\nexport const CommonAddresses: Record<string, string> = {\n ERC7702Delegator: \"0x63c0c19a282a1b52b07dd5a65b58948a07dae32b\",\n};\n\n// Addresses specific to each chain\nexport const ChainAddresses: Record<number, Record<string, string>> = {\n [MAINNET_CHAIN_ID]: {\n PermissionController: \"0x25E5F8B1E7aDf44518d35D5B2271f114e081f0E5\",\n },\n [SEPOLIA_CHAIN_ID]: {\n PermissionController: \"0x44632dfBdCb6D3E21EF613B0ca8A6A0c618F5a37\",\n },\n};\n\n// Billing environment configurations (separate from chain environments)\nconst BILLING_ENVIRONMENTS: Record<\"dev\" | \"prod\", BillingEnvironmentConfig> = {\n dev: {\n billingApiServerURL: \"https://billingapi-dev.eigencloud.xyz\",\n },\n prod: {\n billingApiServerURL: \"https://billingapi.eigencloud.xyz\",\n },\n};\n\n// Chain environment configurations\nconst ENVIRONMENTS: Record<string, Omit<EnvironmentConfig, \"chainID\">> = {\n \"sepolia-dev\": {\n name: \"sepolia\",\n build: \"dev\",\n appControllerAddress: \"0xa86DC1C47cb2518327fB4f9A1627F51966c83B92\",\n permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,\n erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,\n kmsServerURL: \"http://10.128.0.57:8080\",\n userApiServerURL: \"https://userapi-compute-sepolia-dev.eigencloud.xyz\",\n defaultRPCURL: \"https://ethereum-sepolia-rpc.publicnode.com\",\n },\n sepolia: {\n name: \"sepolia\",\n build: \"prod\",\n appControllerAddress: \"0x0dd810a6ffba6a9820a10d97b659f07d8d23d4E2\",\n permissionControllerAddress: ChainAddresses[SEPOLIA_CHAIN_ID].PermissionController,\n erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,\n kmsServerURL: \"http://10.128.15.203:8080\",\n userApiServerURL: \"https://userapi-compute-sepolia-prod.eigencloud.xyz\",\n defaultRPCURL: \"https://ethereum-sepolia-rpc.publicnode.com\",\n },\n \"mainnet-alpha\": {\n name: \"mainnet-alpha\",\n build: \"prod\",\n appControllerAddress: \"0xc38d35Fc995e75342A21CBd6D770305b142Fbe67\",\n permissionControllerAddress: ChainAddresses[MAINNET_CHAIN_ID].PermissionController,\n erc7702DelegatorAddress: CommonAddresses.ERC7702Delegator,\n kmsServerURL: \"http://10.128.0.2:8080\",\n userApiServerURL: \"https://userapi-compute.eigencloud.xyz\",\n defaultRPCURL: \"https://ethereum-rpc.publicnode.com\",\n },\n};\n\nconst CHAIN_ID_TO_ENVIRONMENT: Record<string, string> = {\n [SEPOLIA_CHAIN_ID.toString()]: \"sepolia\",\n [MAINNET_CHAIN_ID.toString()]: \"mainnet-alpha\",\n};\n\n/**\n * Get environment configuration\n */\nexport function getEnvironmentConfig(environment: string, chainID?: bigint): EnvironmentConfig {\n const env = ENVIRONMENTS[environment];\n if (!env) {\n throw new Error(`Unknown environment: ${environment}`);\n }\n\n // Check if environment is available in current build\n if (!isEnvironmentAvailable(environment)) {\n throw new Error(\n `Environment ${environment} is not available in this build type. ` +\n `Available environments: ${getAvailableEnvironments().join(\", \")}`,\n );\n }\n\n // If chainID provided, validate it matches\n if (chainID) {\n const expectedEnv = CHAIN_ID_TO_ENVIRONMENT[chainID.toString()];\n if (expectedEnv && expectedEnv !== environment) {\n throw new Error(`Environment ${environment} does not match chain ID ${chainID}`);\n }\n }\n\n // Determine chain ID from environment if not provided\n // Both \"sepolia\" and \"sepolia-dev\" use Sepolia chain ID\n const resolvedChainID =\n chainID ||\n (environment === \"sepolia\" || environment === \"sepolia-dev\"\n ? SEPOLIA_CHAIN_ID\n : MAINNET_CHAIN_ID);\n\n return {\n ...env,\n chainID: BigInt(resolvedChainID),\n };\n}\n\n/**\n * Get billing environment configuration\n * @param build - The build type (\"dev\" or \"prod\")\n */\nexport function getBillingEnvironmentConfig(build: \"dev\" | \"prod\"): {\n billingApiServerURL: string;\n} {\n const config = BILLING_ENVIRONMENTS[build];\n if (!config) {\n throw new Error(`Unknown billing environment: ${build}`);\n }\n return config;\n}\n\n/**\n * Detect environment from chain ID\n */\nexport function detectEnvironmentFromChainID(chainID: bigint): string | undefined {\n return CHAIN_ID_TO_ENVIRONMENT[chainID.toString()];\n}\n\n/**\n * Get build type from environment variable or build-time constant (defaults to 'prod')\n * BUILD_TYPE_BUILD_TIME is replaced at build time by tsup's define option\n */\n// @ts-ignore - BUILD_TYPE_BUILD_TIME is injected at build time by tsup\ndeclare const BUILD_TYPE_BUILD_TIME: string | undefined;\n\nexport function getBuildType(): \"dev\" | \"prod\" {\n // First check build-time constant (set by tsup define)\n // @ts-ignore - BUILD_TYPE_BUILD_TIME is injected at build time\n const buildTimeType =\n typeof BUILD_TYPE_BUILD_TIME !== \"undefined\" ? BUILD_TYPE_BUILD_TIME?.toLowerCase() : undefined;\n\n // Fall back to runtime environment variable\n const runtimeType = process.env.BUILD_TYPE?.toLowerCase();\n\n const buildType = buildTimeType || runtimeType;\n\n if (buildType === \"dev\") {\n return \"dev\";\n }\n return \"prod\";\n}\n\n/**\n * Get available environments based on build type\n * - dev: only \"sepolia-dev\"\n * - prod: \"sepolia\" and \"mainnet-alpha\"\n */\nexport function getAvailableEnvironments(): string[] {\n const buildType = getBuildType();\n\n if (buildType === \"dev\") {\n return [\"sepolia-dev\"];\n }\n\n // prod build\n return [\"sepolia\", \"mainnet-alpha\"];\n}\n\n/**\n * Check if an environment is available in the current build\n */\nexport function isEnvironmentAvailable(environment: string): boolean {\n return getAvailableEnvironments().includes(environment);\n}\n\n/**\n * Check if environment is mainnet (chain ID 1)\n */\nexport function isMainnet(environmentConfig: EnvironmentConfig): boolean {\n return environmentConfig.chainID === BigInt(MAINNET_CHAIN_ID);\n}\n","/**\n * Docker build operations\n */\n\nimport * as child_process from \"child_process\";\nimport { promisify } from \"util\";\nimport { DOCKER_PLATFORM } from \"../constants\";\nimport { Logger } from \"../types\";\n\nconst exec = promisify(child_process.exec);\n\n/**\n * Build Docker image using docker buildx\n * Streams output in real-time to logger\n */\nexport async function buildDockerImage(\n buildContext: string,\n dockerfilePath: string,\n tag: string,\n logger?: Logger,\n): Promise<void> {\n const args = [\n \"buildx\",\n \"build\",\n \"--platform\",\n DOCKER_PLATFORM,\n \"-t\",\n tag,\n \"-f\",\n dockerfilePath,\n \"--load\",\n \"--progress=plain\",\n buildContext,\n ];\n\n logger?.info(`Building Docker image: ${tag}`);\n logger?.info(``);\n\n return new Promise<void>((resolve, reject) => {\n const process = child_process.spawn(\"docker\", args, {\n cwd: buildContext,\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n // Stream stdout to logger\n process.stdout?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stdout += output;\n // Log each line to info (Docker build output is important)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info(line);\n }\n });\n });\n\n // Stream stderr to logger\n process.stderr?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stderr += output;\n // Log each line to info (Docker build output is important)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info(line);\n }\n });\n });\n\n process.on(\"close\", (code) => {\n if (code !== 0) {\n const errorMessage = stderr || stdout || \"Unknown error\";\n reject(new Error(`Docker build failed: ${errorMessage}`));\n } else {\n resolve();\n }\n });\n\n process.on(\"error\", (error) => {\n reject(new Error(`Failed to start Docker build: ${error.message}`));\n });\n });\n}\n\n/**\n * Check if Docker is running\n */\nexport async function isDockerRunning(): Promise<boolean> {\n try {\n await exec(\"docker info\");\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Ensure Docker is running, throw error if not\n */\nexport async function ensureDockerIsRunning(): Promise<void> {\n const running = await isDockerRunning();\n if (!running) {\n throw new Error(\"Docker is not running. Please start Docker and try again.\");\n }\n}\n","/**\n * Constants used throughout the SDK\n */\n\nimport { sepolia, mainnet } from \"viem/chains\";\n\nexport const SUPPORTED_CHAINS = [mainnet, sepolia] as const;\n\nexport const DOCKER_PLATFORM = \"linux/amd64\";\nexport const REGISTRY_PROPAGATION_WAIT_SECONDS = 3;\nexport const LAYERED_DOCKERFILE_NAME = \"Dockerfile.eigencompute\";\nexport const ENV_SOURCE_SCRIPT_NAME = \"compute-source-env.sh\";\nexport const KMS_CLIENT_BINARY_NAME = \"kms-client\";\nexport const KMS_ENCRYPTION_KEY_NAME = \"kms-encryption-public-key.pem\";\nexport const KMS_SIGNING_KEY_NAME = \"kms-signing-public-key.pem\";\nexport const TLS_KEYGEN_BINARY_NAME = \"tls-keygen\";\nexport const CADDYFILE_NAME = \"Caddyfile\";\nexport const TEMP_IMAGE_PREFIX = \"ecloud-temp-\";\nexport const LAYERED_BUILD_DIR_PREFIX = \"ecloud-layered-build\";\nexport const SHA256_PREFIX = \"sha256:\";\nexport const JWT_FILE_PATH = \"/run/container_launcher/attestation_verifier_claims_token\";\n","/**\n * Docker image layering\n *\n * This module handles adding ecloud components to Docker images\n */\n\nimport Docker from \"dockerode\";\n\nimport * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\n\nimport {\n extractImageConfig,\n checkIfImageAlreadyLayeredForECloud,\n pullDockerImage,\n} from \"./inspect\";\nimport { buildDockerImage } from \"./build\";\nimport { pushDockerImage } from \"./push\";\nimport { processDockerfileTemplate } from \"../templates/dockerfileTemplate\";\nimport { processScriptTemplate } from \"../templates/scriptTemplate\";\nimport { getKMSKeysForEnvironment } from \"../utils/keys\";\n\nimport {\n LAYERED_DOCKERFILE_NAME,\n ENV_SOURCE_SCRIPT_NAME,\n KMS_CLIENT_BINARY_NAME,\n KMS_SIGNING_KEY_NAME,\n TLS_KEYGEN_BINARY_NAME,\n CADDYFILE_NAME,\n LAYERED_BUILD_DIR_PREFIX,\n DOCKER_PLATFORM,\n} from \"../constants\";\n\nimport { getDirname } from \"../utils/dirname\";\n\nimport { EnvironmentConfig, Logger } from \"../types\";\n\n/**\n * Find binary file in tools directory\n * Supports both CLI (bundled) and standalone SDK usage\n */\nfunction findBinary(binaryName: string): string {\n const __dirname = getDirname();\n\n // Try to find SDK root by looking for tools directory\n // Start from current directory and walk up\n let currentDir = __dirname;\n const maxDepth = 10;\n let depth = 0;\n\n while (depth < maxDepth) {\n const toolsPath = path.join(currentDir, \"tools\", binaryName);\n if (fs.existsSync(toolsPath)) {\n return toolsPath;\n }\n\n // Also check if we're in a monorepo structure\n const sdkToolsPath = path.join(currentDir, \"packages\", \"sdk\", \"tools\", binaryName);\n if (fs.existsSync(sdkToolsPath)) {\n return sdkToolsPath;\n }\n\n const parentDir = path.dirname(currentDir);\n if (parentDir === currentDir) {\n break; // Reached filesystem root\n }\n currentDir = parentDir;\n depth++;\n }\n\n // Try relative paths as fallback\n const possiblePaths = [\n path.join(__dirname, \"../../../tools\", binaryName), // Standalone SDK from dist\n path.join(__dirname, \"../../../../tools\", binaryName), // CLI bundled\n path.join(__dirname, \"../../../../../tools\", binaryName), // Alternative CLI path\n path.resolve(__dirname, \"../../../../tools\", binaryName), // From source\n path.resolve(__dirname, \"../../../../../tools\", binaryName), // From source alternative\n ];\n\n for (const possiblePath of possiblePaths) {\n if (fs.existsSync(possiblePath)) {\n return possiblePath;\n }\n }\n\n // Return the most likely path for error messages\n return path.resolve(__dirname, \"../../../../tools\", binaryName);\n}\n\nexport interface BuildAndPushLayeredImageOptions {\n dockerfilePath: string;\n targetImageRef: string;\n logRedirect: string;\n resourceUsageAllow: string;\n envFilePath?: string;\n environmentConfig: EnvironmentConfig;\n}\n\nexport interface LayerRemoteImageIfNeededOptions {\n imageRef: string;\n logRedirect: string;\n resourceUsageAllow: string;\n envFilePath?: string;\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Build and push layered image from Dockerfile\n */\nexport async function buildAndPushLayeredImage(\n options: BuildAndPushLayeredImageOptions,\n logger: Logger,\n): Promise<string> {\n const {\n dockerfilePath,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n } = options;\n\n // 1. Build base image from user's Dockerfile\n const baseImageTag = `ecloud-temp-${path.basename(dockerfilePath).toLowerCase()}`;\n logger.info(`Building base image from ${dockerfilePath}...`);\n\n // Use the directory containing the Dockerfile as build context\n const buildContext = path.dirname(dockerfilePath);\n await buildDockerImage(buildContext, dockerfilePath, baseImageTag, logger);\n\n // 2. Layer the base image\n const docker = new Docker();\n return layerLocalImage(\n {\n docker,\n sourceImageRef: baseImageTag,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n}\n\n/**\n * Layer remote image if needed\n */\nexport async function layerRemoteImageIfNeeded(\n options: LayerRemoteImageIfNeededOptions,\n logger: Logger,\n): Promise<string> {\n const { imageRef, logRedirect, resourceUsageAllow, envFilePath, environmentConfig } = options;\n\n const docker = new Docker();\n\n // Check if image already has ecloud layering\n const alreadyLayered = await checkIfImageAlreadyLayeredForECloud(docker, imageRef);\n if (alreadyLayered) {\n logger.info(\"Image already has ecloud layering\");\n return imageRef;\n }\n\n // Pull image to ensure we have it locally\n logger.info(`Pulling image ${imageRef}...`);\n await pullDockerImage(docker, imageRef, DOCKER_PLATFORM, logger);\n\n // Prompt for target image (to avoid overwriting source)\n // TODO: Make this configurable via options\n const targetImageRef = `${imageRef}-layered`;\n\n logger.info(`Adding ecloud components to create ${targetImageRef} from ${imageRef}...`);\n const layeredImageRef = await layerLocalImage(\n {\n docker,\n sourceImageRef: imageRef,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n\n return layeredImageRef;\n}\n\n/**\n * Layer local image with ecloud components\n */\nasync function layerLocalImage(\n options: {\n docker: Docker;\n sourceImageRef: string;\n targetImageRef: string;\n logRedirect: string;\n resourceUsageAllow: string;\n envFilePath?: string;\n environmentConfig: EnvironmentConfig;\n },\n logger: Logger,\n): Promise<string> {\n const {\n docker,\n sourceImageRef,\n targetImageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n } = options;\n\n // 1. Extract original command and user from source image\n const imageConfig = await extractImageConfig(docker, sourceImageRef);\n const originalCmd = imageConfig.cmd.length > 0 ? imageConfig.cmd : imageConfig.entrypoint;\n const originalUser = imageConfig.user;\n\n // 2. Check if TLS is needed (check for DOMAIN in env file)\n let includeTLS = false;\n if (envFilePath && fs.existsSync(envFilePath)) {\n const envContent = fs.readFileSync(envFilePath, \"utf-8\");\n const domainMatch = envContent.match(/^DOMAIN=(.+)$/m);\n if (domainMatch && domainMatch[1] && domainMatch[1] !== \"localhost\") {\n includeTLS = true;\n logger.debug(`Found DOMAIN=${domainMatch[1]} in ${envFilePath}, including TLS components`);\n }\n }\n\n // 3. Generate template content\n const layeredDockerfileContent = processDockerfileTemplate({\n baseImage: sourceImageRef,\n originalCmd: JSON.stringify(originalCmd),\n originalUser: originalUser,\n logRedirect: logRedirect,\n resourceUsageAllow: resourceUsageAllow,\n includeTLS: includeTLS,\n ecloudCLIVersion: \"0.1.0\", // TODO: Get from package.json\n });\n\n const scriptContent = processScriptTemplate({\n kmsServerURL: environmentConfig.kmsServerURL,\n userAPIURL: environmentConfig.userApiServerURL,\n });\n\n // 4. Setup build directory\n const tempDir = await setupLayeredBuildDirectory(\n environmentConfig,\n layeredDockerfileContent,\n scriptContent,\n includeTLS,\n // logger\n );\n\n try {\n // 5. Build layered image\n logger.info(`Building updated image with ecloud components for ${sourceImageRef}...`);\n const layeredDockerfilePath = path.join(tempDir, LAYERED_DOCKERFILE_NAME);\n await buildDockerImage(tempDir, layeredDockerfilePath, targetImageRef, logger);\n\n // 6. Push to registry\n logger.info(`Publishing updated image to ${targetImageRef}...`);\n await pushDockerImage(docker, targetImageRef, logger);\n\n logger.info(`Successfully published updated image: ${targetImageRef}`);\n return targetImageRef;\n } finally {\n // Cleanup temp directory\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Setup layered build directory with all required files\n */\nasync function setupLayeredBuildDirectory(\n environmentConfig: EnvironmentConfig,\n layeredDockerfileContent: string,\n scriptContent: string,\n includeTLS: boolean,\n // logger?: Logger\n): Promise<string> {\n const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), LAYERED_BUILD_DIR_PREFIX));\n\n try {\n // Write layered Dockerfile\n const layeredDockerfilePath = path.join(tempDir, LAYERED_DOCKERFILE_NAME);\n fs.writeFileSync(layeredDockerfilePath, layeredDockerfileContent, {\n mode: 0o644,\n });\n\n // Write wrapper script\n const scriptPath = path.join(tempDir, ENV_SOURCE_SCRIPT_NAME);\n fs.writeFileSync(scriptPath, scriptContent, { mode: 0o755 });\n\n // Copy KMS keys\n const { signingKey } = getKMSKeysForEnvironment(\n environmentConfig.name,\n environmentConfig.build,\n );\n\n const signingKeyPath = path.join(tempDir, KMS_SIGNING_KEY_NAME);\n fs.writeFileSync(signingKeyPath, signingKey, { mode: 0o644 });\n\n // Copy kms-client binary\n const kmsClientPath = path.join(tempDir, KMS_CLIENT_BINARY_NAME);\n const kmsClientSource = findBinary(\"kms-client-linux-amd64\");\n if (!fs.existsSync(kmsClientSource)) {\n throw new Error(\n `kms-client binary not found. Expected at: ${kmsClientSource}. ` +\n \"Make sure binaries are in packages/sdk/tools/ directory.\",\n );\n }\n fs.copyFileSync(kmsClientSource, kmsClientPath);\n fs.chmodSync(kmsClientPath, 0o755);\n\n // Include TLS components if requested\n if (includeTLS) {\n // Copy tls-keygen binary\n const tlsKeygenPath = path.join(tempDir, TLS_KEYGEN_BINARY_NAME);\n const tlsKeygenSource = findBinary(\"tls-keygen-linux-amd64\");\n if (!fs.existsSync(tlsKeygenSource)) {\n throw new Error(\n `tls-keygen binary not found. Expected at: ${tlsKeygenSource}. ` +\n \"Make sure binaries are in packages/sdk/tools/ directory.\",\n );\n }\n fs.copyFileSync(tlsKeygenSource, tlsKeygenPath);\n fs.chmodSync(tlsKeygenPath, 0o755);\n\n // Handle Caddyfile\n const caddyfilePath = path.join(process.cwd(), CADDYFILE_NAME);\n if (fs.existsSync(caddyfilePath)) {\n const caddyfileContent = fs.readFileSync(caddyfilePath);\n const destCaddyfilePath = path.join(tempDir, CADDYFILE_NAME);\n fs.writeFileSync(destCaddyfilePath, caddyfileContent, { mode: 0o644 });\n } else {\n throw new Error(\n \"TLS is enabled (DOMAIN is set) but Caddyfile not found. \" +\n \"Run configure TLS to set up TLS configuration\",\n );\n }\n }\n\n return tempDir;\n } catch (error) {\n // Cleanup on error\n fs.rmSync(tempDir, { recursive: true, force: true });\n throw error;\n }\n}\n","/**\n * Docker image inspection\n */\n\nimport Docker from \"dockerode\";\n\nimport { DockerImageConfig } from \"../types\";\n\n/**\n * Extract image configuration (CMD, ENTRYPOINT, USER)\n */\nexport async function extractImageConfig(\n docker: Docker,\n imageTag: string,\n): Promise<DockerImageConfig> {\n try {\n const image = docker.getImage(imageTag);\n const inspect = await image.inspect();\n\n const config = inspect.Config || {};\n const cmd = config.Cmd || [];\n const entrypoint = config.Entrypoint || [];\n const user = config.User || \"\";\n const labels = config.Labels || {};\n\n // Use CMD if available, otherwise use ENTRYPOINT\n const originalCmd = cmd.length > 0 ? cmd : entrypoint;\n\n return {\n cmd: originalCmd as string[],\n entrypoint: entrypoint as string[],\n user: user,\n labels: labels,\n };\n } catch (error: any) {\n throw new Error(`Failed to inspect image ${imageTag}: ${error.message}`);\n }\n}\n\n/**\n * Check if image already has ecloud layering\n */\nexport async function checkIfImageAlreadyLayeredForECloud(\n docker: Docker,\n imageTag: string,\n): Promise<boolean> {\n try {\n const config = await extractImageConfig(docker, imageTag);\n return \"eigenx_cli_version\" in config.labels;\n } catch {\n return false;\n }\n}\n\n/**\n * Pull Docker image\n */\nexport async function pullDockerImage(\n docker: Docker,\n imageTag: string,\n platform: string = \"linux/amd64\",\n logger?: { debug?: (msg: string) => void; info?: (msg: string) => void },\n): Promise<void> {\n logger?.info?.(`Pulling image ${imageTag}...`);\n\n return new Promise((resolve, reject) => {\n docker.pull(imageTag, { platform }, (err, stream) => {\n if (err) {\n reject(new Error(`Failed to pull image ${imageTag}: ${err.message}`));\n return;\n }\n\n // Must consume the stream to ensure pull completes\n docker.modem.followProgress(\n stream!,\n (err) => {\n if (err) {\n reject(new Error(`Failed to complete image pull for ${imageTag}: ${err.message}`));\n } else {\n logger?.info?.(`Image pull completed: ${imageTag}`);\n resolve();\n }\n },\n (event: any) => {\n // Log progress events\n if (event && event.status) {\n logger?.info?.(event.status);\n }\n },\n );\n });\n });\n}\n","/**\n * Docker push operations\n */\n\nimport Docker from \"dockerode\";\n\nimport * as fs from \"fs\";\nimport * as os from \"os\";\nimport * as path from \"path\";\nimport * as child_process from \"child_process\";\n\nimport { execFile } from \"child_process\";\nimport { promisify } from \"util\";\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Extract hostname from a registry URL/string for safe comparison\n */\nfunction extractHostname(registry: string): string {\n let hostname = registry.replace(/^https?:\\/\\//, \"\");\n hostname = hostname.split(\"/\")[0];\n hostname = hostname.split(\":\")[0];\n return hostname.toLowerCase();\n}\n\n/**\n * Check if a registry matches Docker Hub\n */\nfunction isDockerHub(registry: string): boolean {\n const hostname = extractHostname(registry);\n return (\n hostname === \"docker.io\" ||\n hostname === \"index.docker.io\" ||\n hostname === \"registry-1.docker.io\"\n );\n}\n\n/**\n * Check if a registry matches Google Container Registry\n */\nfunction isGCR(registry: string): boolean {\n const hostname = extractHostname(registry);\n return hostname === \"gcr.io\" || hostname.endsWith(\".gcr.io\");\n}\n\n/**\n * Extract registry from image reference\n */\nexport function extractRegistry(imageRef: string): string {\n // Handle different registry formats:\n // - docker.io/library/image:tag\n // - ghcr.io/owner/image:tag\n // - gcr.io/project/image:tag\n // - registry.example.com/image:tag\n\n const parts = imageRef.split(\"/\");\n if (parts.length < 2) {\n return \"docker.io\"; // Default to Docker Hub\n }\n\n const firstPart = parts[0];\n\n // Check if first part is a registry (contains . or is a known registry)\n if (firstPart.includes(\".\") || firstPart === \"ghcr.io\" || isGCR(firstPart)) {\n return firstPart;\n }\n\n // Default to Docker Hub\n return \"docker.io\";\n}\n\n/**\n * Get auth config for a specific registry\n * Returns an object with username/password or auth string\n * Handles both direct auth in config.json and credential stores\n */\nexport async function getRegistryAuthConfig(\n registry: string,\n): Promise<{ username?: string; password?: string; auth?: string } | undefined> {\n const authConfig = getDockerAuthConfig();\n\n // Helper to extract auth from config entry\n const extractAuth = (auth: any) => {\n if (!auth) return undefined;\n // If auth string exists, use it\n if (auth.auth) {\n return { auth: auth.auth };\n }\n // If username and password exist, use them\n if (auth.username && auth.password) {\n return { username: auth.username, password: auth.password };\n }\n return undefined;\n };\n\n // Try exact match first\n const exactMatch = extractAuth(authConfig[registry]);\n if (exactMatch) return exactMatch;\n\n // Try with https:// prefix\n const httpsRegistry = `https://${registry}`;\n const httpsMatch = extractAuth(authConfig[httpsRegistry]);\n if (httpsMatch) return httpsMatch;\n\n // For ghcr.io, also try common variants\n if (registry === \"ghcr.io\") {\n const ghcrVariants = [\"ghcr.io\", \"https://ghcr.io\", \"https://ghcr.io/v1/\"];\n for (const variant of ghcrVariants) {\n const match = extractAuth(authConfig[variant]);\n if (match) return match;\n\n // If entry exists but is empty (credential store), try to get from helper\n if (authConfig[variant] && Object.keys(authConfig[variant]).length === 0) {\n const creds = await getCredentialsFromHelper(\"ghcr.io\");\n if (creds) {\n return { username: creds.username, password: creds.password };\n }\n }\n }\n\n // Also try to get from helper even if no entry exists (for credential store only setups)\n const creds = await getCredentialsFromHelper(\"ghcr.io\");\n if (creds) {\n return { username: creds.username, password: creds.password };\n }\n }\n\n // For Docker Hub, try common variants\n if (isDockerHub(registry)) {\n const dockerVariants = [\n \"https://index.docker.io/v1/\",\n \"https://index.docker.io/v1\",\n \"index.docker.io\",\n \"docker.io\",\n ];\n for (const variant of dockerVariants) {\n const match = extractAuth(authConfig[variant]);\n if (match) return match;\n }\n }\n\n return undefined;\n}\n\n/**\n * Push Docker image to registry\n * Uses Docker CLI directly for better credential helper support\n * Streams output in real-time to logger\n */\nexport async function pushDockerImage(\n docker: Docker,\n imageRef: string,\n logger?: { debug?: (msg: string) => void; info?: (msg: string) => void },\n): Promise<void> {\n // Use Docker CLI directly instead of dockerode for better credential helper support\n // Docker CLI automatically handles credential helpers, which dockerode sometimes struggles with\n logger?.info?.(`Pushing image ${imageRef}...`);\n\n return new Promise<void>((resolve, reject) => {\n const process = child_process.spawn(\"docker\", [\"push\", imageRef], {\n stdio: [\"ignore\", \"pipe\", \"pipe\"],\n });\n\n let stdout = \"\";\n let stderr = \"\";\n\n // Stream stdout to logger\n process.stdout?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stdout += output;\n // Log each line to info (Docker push output shows progress)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info?.(line);\n }\n });\n });\n\n // Stream stderr to logger\n process.stderr?.on(\"data\", (data: Buffer) => {\n const output = data.toString();\n stderr += output;\n // Log each line to info (Docker push output shows progress)\n output.split(\"\\n\").forEach((line) => {\n if (line.trim()) {\n logger?.info?.(line);\n }\n });\n });\n\n process.on(\"close\", async (code) => {\n if (code !== 0) {\n const errorMsg = stderr || stdout || \"Unknown error\";\n if (isPermissionError(errorMsg)) {\n reject(new PushPermissionError(imageRef, new Error(errorMsg)));\n } else {\n reject(new Error(`Docker push failed: ${errorMsg}`));\n }\n return;\n }\n\n // Check for success indicators\n const output = stdout + stderr;\n if (!output.includes(\"digest:\") && !output.includes(\"pushed\") && !output.includes(\"Pushed\")) {\n logger?.debug?.(\"No clear success indicator in push output, verifying...\");\n }\n\n logger?.info?.(\"Image push completed successfully\");\n\n // Verify the push by checking if image exists in registry\n // Wait a bit longer for GHCR to process\n try {\n await verifyImageExists(imageRef, logger);\n resolve();\n } catch (error: any) {\n reject(error);\n }\n });\n\n process.on(\"error\", (error) => {\n const msg = error.message || String(error);\n if (msg.includes(\"command not found\") || msg.includes(\"ENOENT\")) {\n reject(\n new Error(`Docker CLI not found. Please ensure Docker is installed and in your PATH.`),\n );\n } else {\n reject(new Error(`Failed to start Docker push: ${msg}`));\n }\n });\n });\n}\n\n/**\n * Verify that the image exists in the registry after push\n */\nasync function verifyImageExists(\n imageRef: string,\n logger?: { debug?: (msg: string) => void; info?: (msg: string) => void },\n): Promise<void> {\n // Wait longer for registry to process (GHCR can be slow)\n logger?.debug?.(\"Waiting for registry to process image...\");\n await new Promise((resolve) => setTimeout(resolve, 3000));\n\n // Retry verification up to 5 times with increasing delays\n let retries = 5;\n\n while (retries > 0) {\n try {\n await execFileAsync(\"docker\", [\"manifest\", \"inspect\", imageRef], {\n maxBuffer: 10 * 1024 * 1024,\n timeout: 10000, // 10 second timeout\n });\n // If we get here, the image exists\n logger?.debug?.(\"Image verified in registry\");\n return;\n } catch (error: any) {\n const errorMsg = error.message || String(error);\n\n // If manifest inspect fails, wait and retry\n if (errorMsg.includes(\"manifest unknown\") || errorMsg.includes(\"not found\")) {\n retries--;\n if (retries > 0) {\n const waitTime = (6 - retries) * 2000; // 2s, 4s, 6s, 8s, 10s\n logger?.debug?.(\n `Image not found yet, retrying in ${waitTime / 1000}s... (${retries} retries left)`,\n );\n await new Promise((resolve) => setTimeout(resolve, waitTime));\n continue;\n }\n // All retries exhausted\n throw new Error(\n `Image push verification failed: Image ${imageRef} was not found in registry after multiple attempts.\\n` +\n `This usually means the push failed. Please check:\\n` +\n `1. Your authentication: docker login ghcr.io\\n` +\n `2. Your permissions: Ensure you have push access to the repository\\n` +\n `3. Try pushing manually: docker push ${imageRef}\\n` +\n `4. Check if the image exists: docker manifest inspect ${imageRef}`,\n );\n }\n // Other errors might be temporary (network issues, etc.)\n // Retry once more\n retries--;\n if (retries > 0) {\n await new Promise((resolve) => setTimeout(resolve, 2000));\n continue;\n }\n // Log a warning but don't fail for non-manifest-unknown errors\n logger?.debug?.(`Warning: Could not verify image push: ${errorMsg}`);\n return;\n }\n }\n}\n\n/**\n * Check if error message indicates a permission/auth issue\n */\nfunction isPermissionError(errMsg: string): boolean {\n const errLower = errMsg.toLowerCase();\n const permissionKeywords = [\n \"denied\",\n \"unauthorized\",\n \"forbidden\",\n \"insufficient_scope\",\n \"authentication required\",\n \"access forbidden\",\n \"permission denied\",\n \"requested access to the resource is denied\",\n ];\n\n return permissionKeywords.some((keyword) => errLower.includes(keyword));\n}\n\n/**\n * Push permission error class\n */\nexport class PushPermissionError extends Error {\n constructor(\n public imageRef: string,\n public originalError: Error,\n ) {\n super(`Permission denied pushing to ${imageRef}: ${originalError.message}`);\n this.name = \"PushPermissionError\";\n }\n}\n\n/**\n * Get Docker auth config from system\n * This reads from ~/.docker/config.json and handles credential stores\n */\nexport function getDockerAuthConfig(): Record<string, any> {\n const dockerConfigPath = path.join(os.homedir(), \".docker\", \"config.json\");\n\n if (!fs.existsSync(dockerConfigPath)) {\n return {};\n }\n\n try {\n const config = JSON.parse(fs.readFileSync(dockerConfigPath, \"utf-8\"));\n const auths = config.auths || {};\n\n // If credsStore is set, credentials are stored in credential helper (e.g., osxkeychain)\n // In this case, dockerode should handle auth automatically, but we still return\n // the auths structure (even if empty) to indicate the registry is configured\n if (config.credsStore) {\n // Return auths as-is (may be empty objects, but registry is configured)\n return auths;\n }\n\n return auths;\n } catch {\n return {};\n }\n}\n\n/**\n * Get credentials from Docker credential helper\n */\nasync function getCredentialsFromHelper(\n registry: string,\n): Promise<{ username: string; password: string } | undefined> {\n const dockerConfigPath = path.join(os.homedir(), \".docker\", \"config.json\");\n\n if (!fs.existsSync(dockerConfigPath)) {\n return undefined;\n }\n\n try {\n const config = JSON.parse(fs.readFileSync(dockerConfigPath, \"utf-8\"));\n const credsStore = config.credsStore;\n\n if (!credsStore) {\n return undefined;\n }\n\n // Use Docker credential helper to get credentials\n // Format: docker-credential-<helper> get <serverURL>\n const { execSync } = await import(\"child_process\");\n const helper = `docker-credential-${credsStore}`;\n\n try {\n const output = execSync(`echo \"${registry}\" | ${helper} get`, {\n encoding: \"utf-8\",\n });\n const creds = JSON.parse(output);\n if (creds.Username && creds.Secret) {\n return { username: creds.Username, password: creds.Secret };\n }\n } catch {\n // Credential helper failed, return undefined\n return undefined;\n }\n } catch {\n return undefined;\n }\n\n return undefined;\n}\n","import Handlebars from \"handlebars\";\nimport dockerfileTemplate from \"./Dockerfile.layered.tmpl\";\n\nexport interface DockerfileTemplateData {\n baseImage: string;\n originalCmd: string; // JSON array string\n originalUser: string;\n logRedirect: string;\n resourceUsageAllow: string; // \"always\" or \"never\" for memory monitoring\n includeTLS: boolean;\n ecloudCLIVersion: string;\n}\n\n/**\n * Process Dockerfile template\n */\nexport function processDockerfileTemplate(data: DockerfileTemplateData): string {\n const template = Handlebars.compile(dockerfileTemplate);\n return template(data);\n}\n","{{#if includeTLS}}\n# Get Caddy from official image\nFROM caddy:2.10.2-alpine AS caddy\n{{/if}}\n\nFROM {{baseImage}}\n\n{{#if originalUser}}\n# Switch to root to perform setup (base image has non-root USER: {{originalUser}})\nUSER root\n{{/if}}\n\n# Copy core TEE components\nCOPY compute-source-env.sh /usr/local/bin/\nCOPY kms-client /usr/local/bin/\nCOPY kms-signing-public-key.pem /usr/local/bin/\n\n{{#if includeTLS}}\n# Copy Caddy from official image\nCOPY --from=caddy /usr/bin/caddy /usr/local/bin/caddy\n\n# Copy TLS components\nCOPY tls-keygen /usr/local/bin/\nCOPY Caddyfile /etc/caddy/\n{{/if}}\n\n{{#if originalUser}}\n# Make binaries executable (755 for executables, 644 for keys)\nRUN chmod 755 /usr/local/bin/compute-source-env.sh \\\n && chmod 755 /usr/local/bin/kms-client{{#if includeTLS}} \\\n && chmod 755 /usr/local/bin/tls-keygen \\\n && chmod 755 /usr/local/bin/caddy{{/if}} \\\n && chmod 644 /usr/local/bin/kms-signing-public-key.pem\n\n# Store original user - entrypoint will drop privileges to this user after TEE setup\nENV __ECLOUD_ORIGINAL_USER={{originalUser}}\n{{else}}\n# Make binaries executable (preserve existing permissions, just add execute)\nRUN chmod +x /usr/local/bin/compute-source-env.sh \\\n && chmod +x /usr/local/bin/kms-client{{#if includeTLS}} \\\n && chmod +x /usr/local/bin/tls-keygen{{/if}}\n{{/if}}\n\n{{#if logRedirect}}\n\nLABEL tee.launch_policy.log_redirect={{logRedirect}}\n{{/if}}\n{{#if resourceUsageAllow}}\n\nLABEL tee.launch_policy.monitoring_memory_allow={{resourceUsageAllow}}\n{{/if}}\n\nLABEL eigenx_cli_version={{ecloudCLIVersion}}\nLABEL eigenx_use_ita=True\n\n{{#if includeTLS}}\n# Expose both HTTP and HTTPS ports for Caddy\nEXPOSE 80 443\n{{/if}}\n\nENTRYPOINT [\"/usr/local/bin/compute-source-env.sh\"]\nCMD {{{originalCmd}}}\n","import Handlebars from \"handlebars\";\nimport scriptTemplate from \"./compute-source-env.sh.tmpl\";\n\nexport interface ScriptTemplateData {\n kmsServerURL: string;\n userAPIURL: string;\n}\n\n/**\n * Process script template\n */\nexport function processScriptTemplate(data: ScriptTemplateData): string {\n const template = Handlebars.compile(scriptTemplate);\n return template(data);\n}\n","#!/bin/sh\necho \"compute-source-env.sh: Running setup script...\"\n\n# Fetch and source environment variables from KMS\necho \"Fetching secrets from KMS...\"\nif /usr/local/bin/kms-client \\\n --kms-server-url \"{{kmsServerURL}}\" \\\n --kms-signing-key-file /usr/local/bin/kms-signing-public-key.pem \\\n --userapi-url \"{{userAPIURL}}\" \\\n --output /tmp/.env; then\n echo \"compute-source-env.sh: Successfully fetched environment variables from KMS\"\n set -a && . /tmp/.env && set +a\n rm -f /tmp/.env\nelse\n echo \"compute-source-env.sh: ERROR - Failed to fetch environment variables from KMS\"\n echo \"compute-source-env.sh: Exiting - cannot start user workload without KMS secrets\"\n exit 1\nfi\n\n# Setup TLS if tls-keygen is present (which means TLS was configured at build time)\nsetup_tls() {\n # If tls-keygen isn't present, TLS wasn't configured during build\n if [ ! -x /usr/local/bin/tls-keygen ]; then\n echo \"compute-source-env.sh: TLS not configured (no tls-keygen binary)\"\n return 0\n fi\n \n local domain=\"${DOMAIN:-}\"\n local mnemonic=\"${MNEMONIC:-}\"\n \n # Since tls-keygen is present, TLS is expected - validate requirements\n if [ -z \"$domain\" ] || [ \"$domain\" = \"localhost\" ]; then\n echo \"compute-source-env.sh: ERROR - TLS binary present but DOMAIN not configured or is localhost\"\n echo \"compute-source-env.sh: Set DOMAIN environment variable to a valid domain\"\n exit 1\n fi\n \n if [ -z \"$mnemonic\" ]; then\n echo \"compute-source-env.sh: ERROR - TLS binary present but MNEMONIC not available\"\n echo \"compute-source-env.sh: Cannot obtain TLS certificate without mnemonic\"\n exit 1\n fi\n \n if [ ! -x /usr/local/bin/caddy ]; then\n echo \"compute-source-env.sh: ERROR - TLS binary present but Caddy not found\"\n exit 1\n fi\n \n echo \"compute-source-env.sh: Setting up TLS for domain: $domain\"\n \n # Obtain TLS certificate using ACME\n # Default to http-01, but allow override via ACME_CHALLENGE env var\n local challenge=\"${ACME_CHALLENGE:-http-01}\"\n \n # Check if we should use staging (for testing)\n local staging_flag=\"\"\n if [ \"${ACME_STAGING:-false}\" = \"true\" ]; then\n staging_flag=\"-staging\"\n echo \"compute-source-env.sh: Using Let's Encrypt STAGING environment (certificates won't be trusted)\"\n fi\n \n echo \"compute-source-env.sh: Obtaining TLS certificate using $challenge challenge...\"\n # Pass the API URL for certificate persistence\n if ! MNEMONIC=\"$mnemonic\" DOMAIN=\"$domain\" API_URL=\"{{userAPIURL}}\" /usr/local/bin/tls-keygen \\\n -challenge \"$challenge\" \\\n $staging_flag; then\n echo \"compute-source-env.sh: ERROR - Failed to obtain TLS certificate\"\n echo \"compute-source-env.sh: Certificate issuance failed for $domain\"\n exit 1\n fi\n \n echo \"compute-source-env.sh: TLS certificate obtained successfully\"\n \n # Validate Caddyfile before starting\n if ! /usr/local/bin/caddy validate --config /etc/caddy/Caddyfile --adapter caddyfile 2>/dev/null; then\n echo \"compute-source-env.sh: ERROR - Invalid Caddyfile\"\n echo \"compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed\"\n exit 1\n fi\n \n # Start Caddy in background\n echo \"compute-source-env.sh: Starting Caddy reverse proxy...\"\n \n # Check if Caddy logs should be enabled\n if [ \"${ENABLE_CADDY_LOGS:-false}\" = \"true\" ]; then\n if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile 2>&1; then\n echo \"compute-source-env.sh: ERROR - Failed to start Caddy\"\n echo \"compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed\"\n exit 1\n fi\n else\n # Redirect Caddy output to /dev/null to silence logs\n if ! /usr/local/bin/caddy start --config /etc/caddy/Caddyfile --adapter caddyfile >/dev/null 2>&1; then\n echo \"compute-source-env.sh: ERROR - Failed to start Caddy\"\n echo \"compute-source-env.sh: TLS was requested (DOMAIN=$domain) but setup failed\"\n exit 1\n fi\n fi\n \n # Give Caddy a moment to fully initialize\n sleep 2\n echo \"compute-source-env.sh: Caddy started successfully\"\n return 0\n}\n\n# Run TLS setup\nsetup_tls\n\necho \"compute-source-env.sh: Environment sourced.\"\n\n# Drop privileges to original user for the application command\nif [ -n \"$__ECLOUD_ORIGINAL_USER\" ] && [ \"$(id -u)\" = \"0\" ]; then\n echo \"compute-source-env.sh: Dropping privileges to user: $__ECLOUD_ORIGINAL_USER\"\n exec su -s /bin/sh \"$__ECLOUD_ORIGINAL_USER\" -c 'exec \"$@\"' -- sh \"$@\"\nfi\n\nexec \"$@\"\n","-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0kHU86k17ofCIGcJKDcf\nAFurFhSLeWmOL0bwWLCeVnTPG0MMHtJOq+woE0XXSWw6lzm+jzavBBTwKde1dgal\nAp91vULAZFMUpiUdd2dNUVtvU89qW0Pgf1Eu5FDj7BkY/SnyECbWJM4ga0BmpiGy\nnQwLNN9mMGhjVoVLn2zwEGZ7JzS9Nz11EZKO/k/9DcO6LaoIFmKuvVf3jl6lvZg8\naeA0LoZXjkycHlRUt/kfKwZnhakUaYHP1ksV7ZNmolS5GYDTSKGB2KPPNR1s4/Xu\nu8zeEFC8HuGRU8XuuBeaAunitnGhbNVREUNJGff6HZOGB6CIFNXjbQETeZ3p5uro\n0v+hd1QqQYBv7+DEaMCmGnJNGAyIMr2mn4vr7wGsIj0HonlSHmQ8rmdUhL2ocNTc\nLhKgZiZmBuDpSbFW/r53R2G7CHcqaqGeUBnT54QCH4zsYKw0/4dOtwFxQpTyBf9/\n+k+KaWEJYKkx9d9OzKGyAvzrTDVOFoajddiJ6LPvRlMdOUQr3hl4IAC0/nh9lhHq\nD0R+i5WAU96TkdAe7B7iTGH2D22k0KUPR6Q9W3aF353SLxQAMPNrgG4QQufAdRJn\nAF+8ntun5TkTqjTWRSwAsUJZ1z4wb96DympWJbDi0OciJRZ3Fz3j9+amC43yCHGg\naaEMjdt35ewbztUSc04F10MCAwEAAQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEfxbhXJjH4D0DH/iW5/rK1HzWS+f9\nEyooZTrCYjCfezuOEmRuOWNaZLvwXN8SdzrvjWA7gSvOS85hLzp4grANRQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAr/vqttU6aXX35HtsXavU\n5teysunDzZB3HyaFM4qcuRnqj+70KxqLOwZsERN5SwZ/56Jm8T2ds1CcXsQCMUMw\n+MPlsF6KMGfzghLtYHONwvKLnn+U9y886aAay6W8a0A7O7YCZehNYD3kQnCXjOIc\nMj6v8AEvMw+w/lNabjRXnwSBMKVIGp/cSL0hGwt8fGoC3TsxQN9opzvU1Z4rAw9K\na119l6dlPnqezDva378TCaXDjqKe/jSZOI1CcYpaSK2SJ+95Wbvte5j3lXbg1oT2\n0rXeJUHEJ68QxMtJplfw0Sg+Ek4CUJ2c/kbdg0u7sIIO5wcB4WHL/Lfbw2XPmcBI\nt0r0EC575D3iHF/aI01Ms2IRA0GDeHnNcr5FJLWJljTjNLEt4tFITrXwBe1Ealm3\nNCxamApl5bBSwQ72Gb5fiQFwB8Fl2/XG3wfGTFInFEvWE4c/H8dtu1wHTsyEFZcG\nB47IkD5GBSZq90Hd9xuZva55dxGpqUVrEJO88SqHGP9Oa+HLTYdEe5AR5Hitw4Mu\ndk1cCH+X5OqY9dfpdoCNbKAM0N2SJvNAnDTU2JKGYheXrnDslXR6atBmU5gDkH+W\nQVryDYl9xbwWIACMQsAQjrrtKw5xqJ4V89+06FN/wyEVF7KWAcJ4AhKiVnCvLqzb\nBbISc+gOkRsefhCDJVPEKDkCAwEAAQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEb2Q88/cxdic2xi4jS2V0dtYHjLwq\n4wVFBFmaY8TTXoMXNggKEdU6PuE8EovocVKMpw3SIlaM27z9uxksNVL2xw==\n-----END PUBLIC KEY-----\n","-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEApDvk8pAivkgtiC5li5MP\nxMTJDduTeorBl18ynrooTxp2BwwgPwXfXbJaCA0qRubvc0aO2uh2VDrPM27CqMLH\no2S9YLtpLii4A1Nl7SE/MdWKWdG6v94xNGpc2YyPP7yWtHfqOkgDWp8sokl3Uq/9\nMS0pjUaI7RyS5boCTy8Qw90BxGMpucjOmqm+luw4EdPWZCrgriUR2bbGRRgAmrT1\nK4ou4IgPp799r120hwHbCWxnOvLdQdpiv2507b900xS/3yZahhnHCAn66146LU/f\nBrRpQKSM0qSpktXrrc9MH/ru2VLR5cGLp89ZcZMQA9cRGglWM5XWVY3Ti2TPJ6Kd\nAn1d7qNkGJaSdVa3x3HkOf6c6HeTyqis5/L/6L+PFhUsTRbmKg1FtwD+3xxdyf7h\nabFxryE9rv+WatHL6r6z5ztV0znJ/Fpfs5A45FWA6pfb28fA59RGpi/DQ8RxgdCH\nnZRNvdz8dTgRaXSPgkfGXBcCFqb/QhFmad7XbWDthGzfhbPOxNPtiaGRQ1Dr/Pgq\nn0ugdLbRQLmDOAFgaQcnr0U4y1TUlWJnvoZMETkVN7gmITtXA4F324ALT7Rd+Lgk\nHikW5vG+NjAEwXfPsK0YzT+VbHd7o1lbru9UxiDlN03XVEkz/oRQi47CvSTo3FSr\n5dB4lz8kov3UUcNJfQFZolMCAwEAAQ==\n-----END PUBLIC KEY-----","-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEsk6ZdmmvBqFfKHs+1cYjIemRGN7h\n1NatIEitFRyx+3q8wmTJ9LknTE1FwWBLcCNTseJDti8Rh+SaVxfGOyJuuA==\n-----END PUBLIC KEY-----","/**\n * KMS key loading utilities\n */\n\n// Import all keys at build time\nimport mainnetAlphaProdEncryption from \"../../../../keys/mainnet-alpha/prod/kms-encryption-public-key.pem\";\nimport mainnetAlphaProdSigning from \"../../../../keys/mainnet-alpha/prod/kms-signing-public-key.pem\";\nimport sepoliaDevEncryption from \"../../../../keys/sepolia/dev/kms-encryption-public-key.pem\";\nimport sepoliaDevSigning from \"../../../../keys/sepolia/dev/kms-signing-public-key.pem\";\nimport sepoliaProdEncryption from \"../../../../keys/sepolia/prod/kms-encryption-public-key.pem\";\nimport sepoliaProdSigning from \"../../../../keys/sepolia/prod/kms-signing-public-key.pem\";\n\ntype KeyMap = {\n [environment: string]: {\n [build: string]: {\n encryption: string;\n signing: string;\n };\n };\n};\n\nconst KEYS: KeyMap = {\n \"mainnet-alpha\": {\n prod: {\n encryption: mainnetAlphaProdEncryption,\n signing: mainnetAlphaProdSigning,\n },\n },\n sepolia: {\n dev: {\n encryption: sepoliaDevEncryption,\n signing: sepoliaDevSigning,\n },\n prod: {\n encryption: sepoliaProdEncryption,\n signing: sepoliaProdSigning,\n },\n },\n};\n\n/**\n * Get KMS keys for environment\n */\nexport function getKMSKeysForEnvironment(\n environment: string,\n build: \"dev\" | \"prod\" = \"prod\",\n): { encryptionKey: Buffer; signingKey: Buffer } {\n const envKeys = KEYS[environment];\n if (!envKeys) {\n throw new Error(`No keys found for environment: ${environment}`);\n }\n\n const buildKeys = envKeys[build];\n if (!buildKeys) {\n throw new Error(`No keys found for environment: ${environment}, build: ${build}`);\n }\n\n return {\n encryptionKey: Buffer.from(buildKeys.encryption),\n signingKey: Buffer.from(buildKeys.signing),\n };\n}\n\n/**\n * Check if keys exist for environment\n */\nexport function keysExistForEnvironment(\n environment: string,\n build: \"dev\" | \"prod\" = \"prod\",\n): boolean {\n return !!KEYS[environment]?.[build];\n}\n","/**\n * ESM and CJS compatible getDirname utility\n */\n\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Get __dirname equivalent that works in both ESM and CJS\n * In CJS builds, __dirname is available and will be used\n * In ESM builds, import.meta.url is used\n */\nexport function getDirname(): string {\n // Check for CJS __dirname first (available in CommonJS)\n if (typeof __dirname !== \"undefined\") {\n return __dirname;\n }\n\n // For ESM, we need to use import.meta.url\n // This will be evaluated at build time by tsup for ESM builds\n // For CJS builds, the above check will catch it, so this won't execute\n try {\n const metaUrl = import.meta.url;\n return path.dirname(fileURLToPath(metaUrl));\n } catch {\n // Fallback (shouldn't reach here in normal usage)\n return process.cwd();\n }\n}\n","/**\n * Image registry operations - digest extraction\n *\n * Uses Docker API to extract image digest and validate platform\n */\n\nimport * as child_process from \"child_process\";\nimport { promisify } from \"util\";\nimport { ImageDigestResult } from \"../types\";\nimport { DOCKER_PLATFORM } from \"../constants\";\n\nconst execFileAsync = promisify(child_process.execFile);\n\ninterface Platform {\n os: string;\n architecture: string;\n}\n\ninterface ManifestManifest {\n digest: string;\n platform?: Platform;\n}\n\ninterface Manifest {\n manifests?: ManifestManifest[];\n config?: {\n digest: string;\n };\n mediaType?: string;\n}\n\n/**\n * Get image digest and registry name from image reference\n * Uses docker manifest inspect to get the manifest\n */\nexport async function getImageDigestAndName(imageRef: string): Promise<ImageDigestResult> {\n try {\n // Use docker manifest inspect to get the manifest safely\n const { stdout } = await execFileAsync(\n \"docker\",\n [\"manifest\", \"inspect\", imageRef],\n { maxBuffer: 10 * 1024 * 1024 }, // 10MB buffer\n );\n\n const manifest: Manifest = JSON.parse(stdout);\n\n // Check if it's a multi-platform manifest (index)\n if (manifest.manifests && manifest.manifests.length > 0) {\n return extractDigestFromMultiPlatform(manifest, imageRef);\n } else {\n // Single-platform image\n return extractDigestFromSinglePlatform(manifest, imageRef);\n }\n } catch (error: any) {\n throw new Error(`Failed to get image digest for ${imageRef}: ${error.message}`);\n }\n}\n\n/**\n * Extract digest from multi-platform image index\n */\nfunction extractDigestFromMultiPlatform(manifest: Manifest, imageRef: string): ImageDigestResult {\n if (!manifest.manifests) {\n throw new Error(`Invalid manifest for ${imageRef}: no manifests found`);\n }\n\n const platforms: string[] = [];\n\n for (const m of manifest.manifests) {\n if (m.platform) {\n const platform = `${m.platform.os}/${m.platform.architecture}`;\n platforms.push(platform);\n\n if (platform === DOCKER_PLATFORM) {\n const digest = hexStringToBytes32(m.digest);\n const registry = extractRegistryName(imageRef);\n return {\n digest,\n registry,\n platform: DOCKER_PLATFORM,\n };\n }\n }\n }\n\n // No compatible platform found\n throw createPlatformErrorMessage(imageRef, platforms);\n}\n\n/**\n * Extract digest from single-platform image\n * For single-platform images, we need to inspect the image config\n */\nasync function extractDigestFromSinglePlatform(\n manifest: Manifest,\n imageRef: string,\n): Promise<ImageDigestResult> {\n // For single-platform images, we need to get the config digest\n // and then inspect the image to get platform info\n try {\n // Use docker inspect to get platform info\n const { stdout } = await execFileAsync(\"docker\", [\"inspect\", imageRef], {\n maxBuffer: 10 * 1024 * 1024,\n });\n\n const inspectData = JSON.parse(stdout);\n if (!inspectData || !inspectData[0]) {\n throw new Error(`Failed to inspect image ${imageRef}`);\n }\n\n const config = inspectData[0].Architecture\n ? {\n os: inspectData[0].Os || \"linux\",\n architecture: inspectData[0].Architecture,\n }\n : null;\n\n if (!config) {\n // Try to get from manifest config digest\n if (manifest.config?.digest) {\n const digest = hexStringToBytes32(manifest.config.digest);\n const registry = extractRegistryName(imageRef);\n // Assume linux/amd64 if we can't determine platform\n return {\n digest,\n registry,\n platform: DOCKER_PLATFORM,\n };\n }\n throw new Error(`Could not determine platform for ${imageRef}`);\n }\n\n const platform = `${config.os}/${config.architecture}`;\n\n if (platform === DOCKER_PLATFORM) {\n // Get digest from RepoDigests or use config digest\n let digest: Uint8Array;\n if (inspectData[0].RepoDigests && inspectData[0].RepoDigests.length > 0) {\n const repoDigest = inspectData[0].RepoDigests[0];\n digest = extractDigestFromRepoDigest(repoDigest);\n } else if (manifest.config?.digest) {\n digest = hexStringToBytes32(manifest.config.digest);\n } else {\n throw new Error(`Could not extract digest for ${imageRef}`);\n }\n\n const registry = extractRegistryName(imageRef);\n return {\n digest,\n registry,\n platform: DOCKER_PLATFORM,\n };\n }\n\n // Platform mismatch\n throw createPlatformErrorMessage(imageRef, [platform]);\n } catch (error: any) {\n if (error.message.includes(\"platform\")) {\n throw error;\n }\n throw new Error(\n `Failed to extract digest from single-platform image ${imageRef}: ${error.message}`,\n );\n }\n}\n\n/**\n * Convert hex string to 32-byte array\n */\nfunction hexStringToBytes32(hexStr: string): Uint8Array {\n // Remove \"sha256:\" prefix if present\n let cleanHex = hexStr;\n if (hexStr.includes(\":\")) {\n cleanHex = hexStr.split(\":\")[1];\n }\n\n // Decode hex string\n const bytes = Buffer.from(cleanHex, \"hex\");\n\n if (bytes.length !== 32) {\n throw new Error(`Digest must be exactly 32 bytes, got ${bytes.length}`);\n }\n\n return new Uint8Array(bytes);\n}\n\n/**\n * Extract digest from repo digest string\n * Format: \"repo@sha256:xxxxx\" -> returns 32-byte digest\n */\nfunction extractDigestFromRepoDigest(repoDigest: string): Uint8Array {\n const prefix = \"@sha256:\";\n const idx = repoDigest.lastIndexOf(prefix);\n if (idx === -1) {\n throw new Error(`Invalid repo digest format: ${repoDigest}`);\n }\n\n const hexDigest = repoDigest.substring(idx + prefix.length);\n return hexStringToBytes32(hexDigest);\n}\n\n/**\n * Extract registry name from image reference\n * e.g., \"ghcr.io/user/repo:tag\" -> \"ghcr.io/user/repo\"\n */\nfunction extractRegistryName(imageRef: string): string {\n // Remove tag if present\n let name = imageRef;\n const tagIndex = name.lastIndexOf(\":\");\n if (tagIndex !== -1 && !name.substring(tagIndex + 1).includes(\"/\")) {\n name = name.substring(0, tagIndex);\n }\n\n // Remove digest if present\n const digestIndex = name.indexOf(\"@\");\n if (digestIndex !== -1) {\n name = name.substring(0, digestIndex);\n }\n\n // Prefix with docker.io/ if no registry is provided\n if ([...name].filter((c) => c === \"/\").length === 1) {\n name = `docker.io/${name}`;\n }\n\n // Default registry\n return name;\n}\n\n/**\n * Create platform error message\n */\nfunction createPlatformErrorMessage(imageRef: string, platforms: string[]): Error {\n const errorMsg = `ecloud requires linux/amd64 images for TEE deployment.\n\nImage: ${imageRef}\nFound platform(s): ${platforms.join(\", \")}\nRequired platform: ${DOCKER_PLATFORM}\n\nTo fix this issue:\n1. Manual fix:\n a. Rebuild your image with the correct platform:\n docker build --platform ${DOCKER_PLATFORM} -t ${imageRef} .\n b. Push the rebuilt image to your remote registry:\n docker push ${imageRef}\n\n2. Or use the SDK to build with the correct platform automatically.`;\n\n return new Error(errorMsg);\n}\n","/**\n * KMS encryption utilities\n * Implements RSA-OAEP-256 + AES-256-GCM encryption using JWE format\n */\n\nimport { Buffer } from \"buffer\";\nimport { importSPKI, CompactEncrypt, type CompactJWEHeaderParameters } from \"jose\";\n\n/**\n * Get app protected headers for encryption\n */\nexport function getAppProtectedHeaders(appID: string): Record<string, string> {\n return {\n \"x-eigenx-app-id\": appID,\n };\n}\n\n/**\n * Encrypt data using RSA-OAEP-256 for key encryption and AES-256-GCM for data encryption\n * Uses jose library which properly implements JWE with RSA-OAEP-256\n */\nexport async function encryptRSAOAEPAndAES256GCM(\n encryptionKeyPEM: string | Buffer,\n plaintext: Buffer,\n protectedHeaders?: Record<string, string> | null,\n): Promise<string> {\n const pemString =\n typeof encryptionKeyPEM === \"string\" ? encryptionKeyPEM : encryptionKeyPEM.toString(\"utf-8\");\n\n // Import RSA public key from PEM format\n // jose handles both PKIX and PKCS#1 formats automatically\n const publicKey = await importSPKI(pemString, \"RSA-OAEP-256\", {\n extractable: true,\n });\n\n // Build protected header\n const header: CompactJWEHeaderParameters = {\n alg: \"RSA-OAEP-256\", // Key encryption algorithm (SHA-256)\n enc: \"A256GCM\", // Content encryption algorithm\n ...(protectedHeaders || {}), // Add custom protected headers\n };\n\n // Encrypt using JWE compact serialization\n // CompactEncrypt is a class that builds and encrypts Compact JWE strings\n // Convert Buffer to Uint8Array for jose library\n const plaintextBytes = new Uint8Array(plaintext);\n const jwe = await new CompactEncrypt(plaintextBytes)\n .setProtectedHeader(header)\n .encrypt(publicKey);\n\n return jwe;\n}\n","/**\n * Environment file parsing and validation\n */\n\nimport * as fs from \"fs\";\nimport { ParsedEnvironment } from \"../types\";\n\nconst MNEMONIC_ENV_VAR = \"MNEMONIC\";\n\n/**\n * Parse environment file and split into public/private variables\n */\nexport function parseAndValidateEnvFile(envFilePath: string): ParsedEnvironment {\n if (!fs.existsSync(envFilePath)) {\n throw new Error(`Environment file not found: ${envFilePath}`);\n }\n\n const content = fs.readFileSync(envFilePath, \"utf-8\");\n const env: Record<string, string> = {};\n let mnemonicFiltered = false;\n\n // Parse .env file (simple parser - can be enhanced)\n const lines = content.split(\"\\n\");\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith(\"#\")) {\n continue;\n }\n\n const equalIndex = trimmed.indexOf(\"=\");\n if (equalIndex === -1) {\n continue;\n }\n\n const key = trimmed.substring(0, equalIndex).trim();\n let value = trimmed.substring(equalIndex + 1).trim();\n\n // Remove quotes if present\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n // Filter out mnemonic\n if (key.toUpperCase() === MNEMONIC_ENV_VAR) {\n mnemonicFiltered = true;\n continue;\n }\n\n env[key] = value;\n }\n\n // Split into public and private\n const publicEnv: Record<string, string> = {};\n const privateEnv: Record<string, string> = {};\n\n for (const [key, value] of Object.entries(env)) {\n if (key.endsWith(\"_PUBLIC\")) {\n publicEnv[key] = value;\n } else {\n privateEnv[key] = value;\n }\n }\n\n return {\n public: publicEnv,\n private: privateEnv,\n // Include mnemonicFiltered flag for logging\n _mnemonicFiltered: mnemonicFiltered,\n } as ParsedEnvironment & { _mnemonicFiltered?: boolean };\n}\n\n/**\n * Display environment variables for user confirmation\n */\nexport function displayEnvironmentVariables(\n parsed: ParsedEnvironment & { _mnemonicFiltered?: boolean },\n): void {\n console.log(\"\\nYour container will deploy with the following environment variables:\\n\");\n\n if (parsed._mnemonicFiltered) {\n console.log(\n \"\\x1b[3;36mMnemonic environment variable removed to be overridden by protocol provided mnemonic\\x1b[0m\\n\",\n );\n }\n\n // Print public variables\n if (Object.keys(parsed.public).length > 0) {\n console.log(\"PUBLIC VARIABLE\\tVALUE\");\n console.log(\"---------------\\t-----\");\n for (const [key, value] of Object.entries(parsed.public)) {\n console.log(`${key}\\t${value}`);\n }\n } else {\n console.log(\"No public variables found\");\n }\n\n console.log(\"\\n-----------------------------------------\\n\");\n\n // Print private variables\n if (Object.keys(parsed.private).length > 0) {\n console.log(\"PRIVATE VARIABLE\\tVALUE\");\n console.log(\"----------------\\t-----\\n\");\n for (const [key, value] of Object.entries(parsed.private)) {\n // Mask private values for display\n const masked =\n value.length > 8\n ? `${value.substring(0, 4)}...${value.substring(value.length - 4)}`\n : \"***\";\n console.log(`${key}\\t${masked}`);\n }\n } else {\n console.log(\"No private variables found\");\n }\n\n console.log();\n}\n","/**\n * Release preparation\n *\n * This module handles building/layering images, encrypting environment variables,\n * and creating the release struct.\n */\n\nimport { buildAndPushLayeredImage } from \"../docker/layer\";\nimport { layerRemoteImageIfNeeded } from \"../docker/layer\";\nimport { getImageDigestAndName } from \"../registry/digest\";\nimport { encryptRSAOAEPAndAES256GCM, getAppProtectedHeaders } from \"../encryption/kms\"; // getAppProtectedHeaders\nimport { getKMSKeysForEnvironment } from \"../utils/keys\";\nimport { REGISTRY_PROPAGATION_WAIT_SECONDS } from \"../constants\";\n\nimport { parseAndValidateEnvFile } from \"../env/parser\";\n\nimport { Release, EnvironmentConfig, Logger } from \"../types\";\nimport { Hex } from \"viem\";\n\nexport interface PrepareReleaseOptions {\n dockerfilePath?: string;\n imageRef: string;\n envFilePath?: string;\n logRedirect: string;\n resourceUsageAllow: string;\n instanceType: string;\n environmentConfig: EnvironmentConfig;\n appId: Hex;\n}\n\nexport interface PrepareReleaseResult {\n release: Release;\n finalImageRef: string;\n}\n\n/**\n * Prepare release from context\n */\nexport async function prepareRelease(\n options: PrepareReleaseOptions,\n logger: Logger,\n): Promise<PrepareReleaseResult> {\n const {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig,\n } = options;\n\n let finalImageRef = imageRef;\n\n // 1. Build/layer image if needed\n if (dockerfilePath) {\n // Build from Dockerfile\n logger.info(\"Building and pushing layered image...\");\n finalImageRef = await buildAndPushLayeredImage(\n {\n dockerfilePath,\n targetImageRef: imageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n\n // Wait for registry propagation\n logger.info(`Waiting ${REGISTRY_PROPAGATION_WAIT_SECONDS} seconds for registry propagation...`);\n await new Promise((resolve) => setTimeout(resolve, REGISTRY_PROPAGATION_WAIT_SECONDS * 1000));\n } else {\n // Layer remote image if needed\n logger.info(\"Checking if image needs layering...\");\n finalImageRef = await layerRemoteImageIfNeeded(\n {\n imageRef,\n logRedirect,\n resourceUsageAllow,\n envFilePath,\n environmentConfig,\n },\n logger,\n );\n\n // Wait for registry propagation if image was layered\n if (finalImageRef !== imageRef) {\n logger.info(\n `Waiting ${REGISTRY_PROPAGATION_WAIT_SECONDS} seconds for registry propagation...`,\n );\n await new Promise((resolve) => setTimeout(resolve, REGISTRY_PROPAGATION_WAIT_SECONDS * 1000));\n }\n }\n\n // 2. Wait a moment for registry to process the push (especially for GHCR)\n logger.info(\"Waiting for registry to process image...\");\n await new Promise((resolve) => setTimeout(resolve, 2000));\n\n // 3. Get image digest and registry name\n logger.info(\"Extracting image digest...\");\n let digest: Uint8Array | undefined;\n let registry: string | undefined;\n\n // Retry getting digest in case registry needs more time\n let retries = 3;\n let lastError: Error | null = null;\n\n while (retries > 0) {\n try {\n const result = await getImageDigestAndName(finalImageRef);\n digest = result.digest;\n registry = result.registry;\n break;\n } catch (error: any) {\n lastError = error;\n retries--;\n if (retries > 0) {\n logger.info(`Digest extraction failed, retrying in 2 seconds... (${retries} retries left)`);\n await new Promise((resolve) => setTimeout(resolve, 2000));\n }\n }\n }\n\n if (!digest || !registry) {\n throw new Error(\n `Failed to get image digest after retries. This usually means the image wasn't pushed successfully.\\n` +\n `Original error: ${lastError?.message}\\n` +\n `Please verify the image exists: docker manifest inspect ${finalImageRef}`,\n );\n }\n\n logger.info(`Image digest: ${Buffer.from(digest).toString(\"hex\")}`);\n logger.info(`Registry: ${registry}`);\n\n // 4. Parse and validate environment file\n let publicEnv: Record<string, string> = {};\n let privateEnv: Record<string, string> = {};\n\n if (envFilePath) {\n logger.info(\"Parsing environment file...\");\n const parsed = parseAndValidateEnvFile(envFilePath);\n publicEnv = parsed.public;\n privateEnv = parsed.private;\n } else {\n logger.info(\"Continuing without environment file\");\n }\n\n // 4. Add instance type to public env\n publicEnv[\"EIGEN_MACHINE_TYPE_PUBLIC\"] = instanceType;\n logger.info(`Instance type: ${instanceType}`);\n\n // 5. Encrypt private environment variables\n logger.info(\"Encrypting environment variables...\");\n const { encryptionKey } = getKMSKeysForEnvironment(\n environmentConfig.name,\n environmentConfig.build,\n );\n const protectedHeaders = getAppProtectedHeaders(options.appId);\n const privateEnvBytes = Buffer.from(JSON.stringify(privateEnv));\n const encryptedEnvStr = await encryptRSAOAEPAndAES256GCM(\n encryptionKey,\n privateEnvBytes,\n protectedHeaders,\n );\n\n // 6. Create release struct\n const release: Release = {\n rmsRelease: {\n artifacts: [\n {\n digest: new Uint8Array(digest),\n registry: registry,\n },\n ],\n upgradeByTime: Math.floor(Date.now() / 1000) + 3600, // 1 hour from now\n },\n publicEnv: new Uint8Array(Buffer.from(JSON.stringify(publicEnv))),\n encryptedEnv: new Uint8Array(Buffer.from(encryptedEnvStr)),\n };\n\n return {\n release,\n finalImageRef,\n };\n}\n","/**\n * Contract interactions\n *\n * This module handles on-chain contract interactions using viem\n */\n\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { executeBatch, checkERC7702Delegation } from \"./eip7702\";\nimport {\n createWalletClient,\n createPublicClient,\n http,\n Address,\n Hex,\n encodeFunctionData,\n decodeErrorResult,\n} from \"viem\";\nimport type { WalletClient, PublicClient } from \"viem\";\nimport { hashAuthorization } from \"viem/utils\";\nimport { sign } from \"viem/accounts\";\n\nimport { addHexPrefix, getChainFromID } from \"../utils\";\n\nimport { EnvironmentConfig, Logger, PreparedDeployData, PreparedUpgradeData } from \"../types\";\nimport { Release } from \"../types\";\n\nimport AppControllerABI from \"../abis/AppController.json\";\nimport PermissionControllerABI from \"../abis/PermissionController.json\";\n\n/**\n * Gas estimation result\n */\nexport interface GasEstimate {\n /** Estimated gas limit for the transaction */\n gasLimit: bigint;\n /** Max fee per gas (EIP-1559) */\n maxFeePerGas: bigint;\n /** Max priority fee per gas (EIP-1559) */\n maxPriorityFeePerGas: bigint;\n /** Maximum cost in wei (gasLimit * maxFeePerGas) */\n maxCostWei: bigint;\n /** Maximum cost formatted as ETH string */\n maxCostEth: string;\n}\n\n/**\n * Options for estimating transaction gas\n */\nexport interface EstimateGasOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n to: Address;\n data: Hex;\n value?: bigint;\n}\n\n/**\n * Format Wei to ETH string\n */\nexport function formatETH(wei: bigint): string {\n const eth = Number(wei) / 1e18;\n const costStr = eth.toFixed(6);\n // Remove trailing zeros and decimal point if needed\n const trimmed = costStr.replace(/\\.?0+$/, \"\");\n // If result is \"0\", show \"<0.000001\" for small amounts\n if (trimmed === \"0\" && wei > 0n) {\n return \"<0.000001\";\n }\n return trimmed;\n}\n\n/**\n * Estimate gas cost for a transaction\n *\n * Use this to get cost estimate before prompting user for confirmation.\n */\nexport async function estimateTransactionGas(options: EstimateGasOptions): Promise<GasEstimate> {\n const { privateKey, rpcUrl, environmentConfig, to, data, value = 0n } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Get current gas prices\n const fees = await publicClient.estimateFeesPerGas();\n\n // Estimate gas for the transaction\n const gasLimit = await publicClient.estimateGas({\n account: account.address,\n to,\n data,\n value,\n });\n\n const maxFeePerGas = fees.maxFeePerGas;\n const maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n const maxCostWei = gasLimit * maxFeePerGas;\n const maxCostEth = formatETH(maxCostWei);\n\n return {\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n maxCostWei,\n maxCostEth,\n };\n}\n\nexport interface DeployAppOptions {\n privateKey: string; // Will be converted to Hex\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n salt: Uint8Array;\n release: Release;\n publicLogs: boolean;\n imageRef: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Prepared deploy batch ready for gas estimation and execution\n */\nexport interface PreparedDeployBatch {\n /** The app ID that will be deployed */\n appId: Address;\n /** The salt used for deployment */\n salt: Uint8Array;\n /** Batch executions to be sent */\n executions: Array<{ target: Address; value: bigint; callData: Hex }>;\n /** Wallet client for sending transaction */\n walletClient: WalletClient;\n /** Public client for reading chain state */\n publicClient: PublicClient;\n /** Environment configuration */\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Prepared upgrade batch ready for gas estimation and execution\n */\nexport interface PreparedUpgradeBatch {\n /** The app ID being upgraded */\n appId: Address;\n /** Batch executions to be sent */\n executions: Array<{ target: Address; value: bigint; callData: Hex }>;\n /** Wallet client for sending transaction */\n walletClient: WalletClient;\n /** Public client for reading chain state */\n publicClient: PublicClient;\n /** Environment configuration */\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Calculate app ID from owner address and salt\n */\nexport async function calculateAppID(\n privateKey: string | Hex,\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n salt: Uint8Array,\n): Promise<Address> {\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Ensure salt is properly formatted as hex string (32 bytes = 64 hex chars)\n const saltHexString = Buffer.from(salt).toString(\"hex\");\n // Pad to 64 characters if needed\n const paddedSaltHex = saltHexString.padStart(64, \"0\");\n const saltHex = `0x${paddedSaltHex}` as Hex;\n\n // Ensure address is a string (viem might return Hex type)\n const accountAddress =\n typeof account.address === \"string\" ? account.address : (account.address as Buffer).toString();\n\n const appID = await publicClient.readContract({\n address: environmentConfig.appControllerAddress,\n abi: AppControllerABI,\n functionName: \"calculateAppId\",\n args: [accountAddress as Address, saltHex],\n });\n\n return appID as Address;\n}\n\n/**\n * Options for preparing a deploy batch\n */\nexport interface PrepareDeployBatchOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n salt: Uint8Array;\n release: Release;\n publicLogs: boolean;\n}\n\n/**\n * Prepare deploy batch - creates executions without sending transaction\n *\n * Use this to get the prepared batch for gas estimation before executing.\n */\nexport async function prepareDeployBatch(\n options: PrepareDeployBatchOptions,\n logger: Logger,\n): Promise<PreparedDeployBatch> {\n const { privateKey, rpcUrl, environmentConfig, salt, release, publicLogs } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // 1. Calculate app ID\n logger.info(\"Calculating app ID...\");\n const appId = await calculateAppID(privateKeyHex, rpcUrl, environmentConfig, salt);\n logger.info(`App ID: ${appId}`);\n\n // Verify the app ID calculation matches what createApp will deploy\n logger.debug(`App ID calculated: ${appId}`);\n logger.debug(`This address will be used for acceptAdmin call`);\n\n // 2. Pack create app call\n const saltHexString = Buffer.from(salt).toString(\"hex\");\n const paddedSaltHex = saltHexString.padStart(64, \"0\");\n const saltHex = `0x${paddedSaltHex}` as Hex;\n\n // Convert Release Uint8Array values to hex strings for viem\n const releaseForViem = {\n rmsRelease: {\n artifacts: release.rmsRelease.artifacts.map((artifact) => ({\n digest: `0x${Buffer.from(artifact.digest).toString(\"hex\").padStart(64, \"0\")}` as Hex,\n registry: artifact.registry,\n })),\n upgradeByTime: release.rmsRelease.upgradeByTime,\n },\n publicEnv: `0x${Buffer.from(release.publicEnv).toString(\"hex\")}` as Hex,\n encryptedEnv: `0x${Buffer.from(release.encryptedEnv).toString(\"hex\")}` as Hex,\n };\n\n const createData = encodeFunctionData({\n abi: AppControllerABI,\n functionName: \"createApp\",\n args: [saltHex, releaseForViem],\n });\n\n // 3. Pack accept admin call\n const acceptAdminData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"acceptAdmin\",\n args: [appId],\n });\n\n // 4. Assemble executions\n // CRITICAL: Order matters! createApp must complete first\n const executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }> = [\n {\n target: environmentConfig.appControllerAddress,\n value: 0n,\n callData: createData,\n },\n {\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: acceptAdminData,\n },\n ];\n\n // 5. Add public logs permission if requested\n if (publicLogs) {\n const anyoneCanViewLogsData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"setAppointee\",\n args: [\n appId,\n \"0x493219d9949348178af1f58740655951a8cd110c\" as Address, // AnyoneCanCallAddress\n \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address, // ApiPermissionsTarget\n \"0x2fd3f2fe\" as Hex, // CanViewAppLogsPermission\n ],\n });\n executions.push({\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: anyoneCanViewLogsData,\n });\n }\n\n return {\n appId,\n salt,\n executions,\n walletClient,\n publicClient,\n environmentConfig,\n };\n}\n\n/**\n * Execute a prepared deploy batch\n */\nexport async function executeDeployBatch(\n data: PreparedDeployData,\n context: {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n },\n gas: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint } | undefined,\n logger: Logger,\n): Promise<{ appId: Address; txHash: Hex }> {\n const pendingMessage = \"Deploying new app...\";\n\n const txHash = await executeBatch(\n {\n walletClient: context.walletClient,\n publicClient: context.publicClient,\n environmentConfig: context.environmentConfig,\n executions: data.executions,\n pendingMessage,\n gas,\n },\n logger,\n );\n\n return { appId: data.appId, txHash };\n}\n\n/**\n * Deploy app on-chain (convenience wrapper that prepares and executes)\n */\nexport async function deployApp(\n options: DeployAppOptions,\n logger: Logger,\n): Promise<{ appId: Address; txHash: Hex }> {\n const prepared = await prepareDeployBatch(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environmentConfig: options.environmentConfig,\n salt: options.salt,\n release: options.release,\n publicLogs: options.publicLogs,\n },\n logger,\n );\n\n // Extract data and context from prepared batch\n const data: PreparedDeployData = {\n appId: prepared.appId,\n salt: prepared.salt,\n executions: prepared.executions,\n };\n const context = {\n walletClient: prepared.walletClient,\n publicClient: prepared.publicClient,\n environmentConfig: prepared.environmentConfig,\n };\n\n return executeDeployBatch(data, context, options.gas, logger);\n}\n\nexport interface UpgradeAppOptions {\n privateKey: string; // Will be converted to Hex\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n release: Release;\n publicLogs: boolean;\n needsPermissionChange: boolean;\n imageRef: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Options for preparing an upgrade batch\n */\nexport interface PrepareUpgradeBatchOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n release: Release;\n publicLogs: boolean;\n needsPermissionChange: boolean;\n}\n\n/**\n * Prepare upgrade batch - creates executions without sending transaction\n *\n * Use this to get the prepared batch for gas estimation before executing.\n */\nexport async function prepareUpgradeBatch(\n options: PrepareUpgradeBatchOptions,\n): Promise<PreparedUpgradeBatch> {\n const {\n privateKey,\n rpcUrl,\n environmentConfig,\n appId,\n release,\n publicLogs,\n needsPermissionChange,\n } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // 1. Pack upgrade app call\n // Convert Release Uint8Array values to hex strings for viem\n const releaseForViem = {\n rmsRelease: {\n artifacts: release.rmsRelease.artifacts.map((artifact) => ({\n digest: `0x${Buffer.from(artifact.digest).toString(\"hex\").padStart(64, \"0\")}` as Hex,\n registry: artifact.registry,\n })),\n upgradeByTime: release.rmsRelease.upgradeByTime,\n },\n publicEnv: `0x${Buffer.from(release.publicEnv).toString(\"hex\")}` as Hex,\n encryptedEnv: `0x${Buffer.from(release.encryptedEnv).toString(\"hex\")}` as Hex,\n };\n\n const upgradeData = encodeFunctionData({\n abi: AppControllerABI,\n functionName: \"upgradeApp\",\n args: [appId, releaseForViem],\n });\n\n // 2. Start with upgrade execution\n const executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }> = [\n {\n target: environmentConfig.appControllerAddress,\n value: 0n,\n callData: upgradeData,\n },\n ];\n\n // 3. Add permission transaction if needed\n if (needsPermissionChange) {\n if (publicLogs) {\n // Add public permission (private→public)\n const addLogsData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"setAppointee\",\n args: [\n appId,\n \"0x493219d9949348178af1f58740655951a8cd110c\" as Address, // AnyoneCanCallAddress\n \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address, // ApiPermissionsTarget\n \"0x2fd3f2fe\" as Hex, // CanViewAppLogsPermission\n ],\n });\n executions.push({\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: addLogsData,\n });\n } else {\n // Remove public permission (public→private)\n const removeLogsData = encodeFunctionData({\n abi: PermissionControllerABI,\n functionName: \"removeAppointee\",\n args: [\n appId,\n \"0x493219d9949348178af1f58740655951a8cd110c\" as Address, // AnyoneCanCallAddress\n \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address, // ApiPermissionsTarget\n \"0x2fd3f2fe\" as Hex, // CanViewAppLogsPermission\n ],\n });\n executions.push({\n target: environmentConfig.permissionControllerAddress as Address,\n value: 0n,\n callData: removeLogsData,\n });\n }\n }\n\n return {\n appId,\n executions,\n walletClient,\n publicClient,\n environmentConfig,\n };\n}\n\n/**\n * Execute a prepared upgrade batch\n */\nexport async function executeUpgradeBatch(\n data: PreparedUpgradeData,\n context: {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n },\n gas: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint } | undefined,\n logger: Logger,\n): Promise<Hex> {\n const pendingMessage = `Upgrading app ${data.appId}...`;\n\n const txHash = await executeBatch(\n {\n walletClient: context.walletClient,\n publicClient: context.publicClient,\n environmentConfig: context.environmentConfig,\n executions: data.executions,\n pendingMessage,\n gas,\n },\n logger,\n );\n\n return txHash;\n}\n\n/**\n * Upgrade app on-chain (convenience wrapper that prepares and executes)\n */\nexport async function upgradeApp(options: UpgradeAppOptions, logger: Logger): Promise<Hex> {\n const prepared = await prepareUpgradeBatch({\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environmentConfig: options.environmentConfig,\n appId: options.appId,\n release: options.release,\n publicLogs: options.publicLogs,\n needsPermissionChange: options.needsPermissionChange,\n });\n\n // Extract data and context from prepared batch\n const data: PreparedUpgradeData = {\n appId: prepared.appId,\n executions: prepared.executions,\n };\n const context = {\n walletClient: prepared.walletClient,\n publicClient: prepared.publicClient,\n environmentConfig: prepared.environmentConfig,\n };\n\n return executeUpgradeBatch(data, context, options.gas, logger);\n}\n\n/**\n * Send and wait for transaction with confirmation support\n */\nexport interface SendTransactionOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n to: Address;\n data: Hex;\n value?: bigint;\n pendingMessage: string;\n txDescription: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\nexport async function sendAndWaitForTransaction(\n options: SendTransactionOptions,\n logger: Logger,\n): Promise<Hex> {\n const {\n privateKey,\n rpcUrl,\n environmentConfig,\n to,\n data,\n value = 0n,\n pendingMessage,\n txDescription,\n gas,\n } = options;\n\n const privateKeyHex = addHexPrefix(privateKey) as Hex;\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // Show pending message if provided\n if (pendingMessage) {\n logger.info(`\\n${pendingMessage}`);\n }\n\n // Send transaction with optional gas params\n const hash = await walletClient.sendTransaction({\n account,\n to,\n data,\n value,\n ...(gas?.maxFeePerGas && { maxFeePerGas: gas.maxFeePerGas }),\n ...(gas?.maxPriorityFeePerGas && { maxPriorityFeePerGas: gas.maxPriorityFeePerGas }),\n });\n\n logger.info(`Transaction sent: ${hash}`);\n\n // Wait for receipt\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status === \"reverted\") {\n let revertReason = \"Unknown reason\";\n try {\n await publicClient.call({\n to,\n data,\n account: account.address,\n });\n } catch (callError: any) {\n if (callError.data) {\n try {\n const decoded = decodeErrorResult({\n abi: AppControllerABI,\n data: callError.data,\n });\n const formattedError = formatAppControllerError(decoded);\n revertReason = formattedError.message;\n } catch {\n revertReason = callError.message || \"Unknown reason\";\n }\n } else {\n revertReason = callError.message || \"Unknown reason\";\n }\n }\n logger.error(`${txDescription} transaction (hash: ${hash}) reverted: ${revertReason}`);\n throw new Error(`${txDescription} transaction (hash: ${hash}) reverted: ${revertReason}`);\n }\n\n return hash;\n}\n\n/**\n * Format AppController errors to user-friendly messages\n */\nfunction formatAppControllerError(decoded: {\n errorName: string;\n args?: readonly unknown[];\n}): Error {\n const errorName = decoded.errorName;\n\n switch (errorName) {\n case \"MaxActiveAppsExceeded\":\n return new Error(\n \"you have reached your app deployment limit. To request access or increase your limit, please visit https://onboarding.eigencloud.xyz/ or reach out to the Eigen team\",\n );\n case \"GlobalMaxActiveAppsExceeded\":\n return new Error(\n \"the platform has reached the maximum number of active apps. please try again later\",\n );\n case \"InvalidPermissions\":\n return new Error(\"you don't have permission to perform this operation\");\n case \"AppAlreadyExists\":\n return new Error(\"an app with this owner and salt already exists\");\n case \"AppDoesNotExist\":\n return new Error(\"the specified app does not exist\");\n case \"InvalidAppStatus\":\n return new Error(\"the app is in an invalid state for this operation\");\n case \"MoreThanOneArtifact\":\n return new Error(\"only one artifact is allowed per release\");\n case \"InvalidSignature\":\n return new Error(\"invalid signature provided\");\n case \"SignatureExpired\":\n return new Error(\"the provided signature has expired\");\n case \"InvalidReleaseMetadataURI\":\n return new Error(\"invalid release metadata URI provided\");\n case \"InvalidShortString\":\n return new Error(\"invalid short string format\");\n default:\n return new Error(`contract error: ${errorName}`);\n }\n}\n\n/**\n * Get active app count for a user\n */\nexport async function getActiveAppCount(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n user: Address,\n): Promise<number> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const count = await publicClient.readContract({\n address: environmentConfig.appControllerAddress,\n abi: AppControllerABI,\n functionName: \"getActiveAppCount\",\n args: [user],\n });\n\n return Number(count);\n}\n\n/**\n * Get max active apps per user (quota limit)\n */\nexport async function getMaxActiveAppsPerUser(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n user: Address,\n): Promise<number> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const quota = await publicClient.readContract({\n address: environmentConfig.appControllerAddress,\n abi: AppControllerABI,\n functionName: \"getMaxActiveAppsPerUser\",\n args: [user],\n });\n\n return Number(quota);\n}\n\n/**\n * Get apps by creator (paginated)\n */\nexport interface AppConfig {\n release: any; // Release struct from contract\n status: number; // AppStatus enum\n}\n\nexport async function getAppsByCreator(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n creator: Address,\n offset: bigint,\n limit: bigint,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const result = (await publicClient.readContract({\n address: environmentConfig.appControllerAddress,\n abi: AppControllerABI,\n functionName: \"getAppsByCreator\",\n args: [creator, offset, limit],\n })) as [Address[], AppConfig[]];\n\n // Result is a tuple: [Address[], AppConfig[]]\n return {\n apps: result[0],\n appConfigs: result[1],\n };\n}\n\n/**\n * Get apps by developer\n */\nexport async function getAppsByDeveloper(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n developer: Address,\n offset: bigint,\n limit: bigint,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const result = (await publicClient.readContract({\n address: environmentConfig.appControllerAddress,\n abi: AppControllerABI,\n functionName: \"getAppsByDeveloper\",\n args: [developer, offset, limit],\n })) as [Address[], AppConfig[]];\n\n // Result is a tuple: [Address[], AppConfig[]]\n return {\n apps: result[0],\n appConfigs: result[1],\n };\n}\n\n/**\n * Fetch all apps by a developer by auto-pagination\n */\nexport async function getAllAppsByDeveloper(\n rpcUrl: string,\n env: EnvironmentConfig,\n developer: Address,\n pageSize: bigint = 100n,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\n let offset = 0n;\n const allApps: Address[] = [];\n const allConfigs: AppConfig[] = [];\n\n while (true) {\n const { apps, appConfigs } = await getAppsByDeveloper(rpcUrl, env, developer, offset, pageSize);\n\n if (apps.length === 0) break;\n\n allApps.push(...apps);\n allConfigs.push(...appConfigs);\n\n if (apps.length < Number(pageSize)) break;\n\n offset += pageSize;\n }\n\n return {\n apps: allApps,\n appConfigs: allConfigs,\n };\n}\n\n/**\n * Get latest release block numbers for multiple apps\n */\nexport async function getAppLatestReleaseBlockNumbers(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n appIDs: Address[],\n): Promise<Map<Address, number>> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Fetch block numbers in parallel\n const results = await Promise.all(\n appIDs.map((appID) =>\n publicClient\n .readContract({\n address: environmentConfig.appControllerAddress,\n abi: AppControllerABI,\n functionName: \"getAppLatestReleaseBlockNumber\",\n args: [appID],\n })\n .catch(() => null),\n ),\n );\n\n const blockNumbers = new Map<Address, number>();\n for (let i = 0; i < appIDs.length; i++) {\n const result = results[i];\n if (result !== null && result !== undefined) {\n blockNumbers.set(appIDs[i], Number(result));\n }\n }\n\n return blockNumbers;\n}\n\n/**\n * Get block timestamps for multiple block numbers\n */\nexport async function getBlockTimestamps(\n rpcUrl: string,\n environmentConfig: EnvironmentConfig,\n blockNumbers: number[],\n): Promise<Map<number, number>> {\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n // Deduplicate block numbers\n const uniqueBlockNumbers = [...new Set(blockNumbers)].filter((n) => n > 0);\n\n const timestamps = new Map<number, number>();\n\n // Fetch blocks in parallel\n const blocks = await Promise.all(\n uniqueBlockNumbers.map((blockNumber) =>\n publicClient.getBlock({ blockNumber: BigInt(blockNumber) }).catch(() => null),\n ),\n );\n\n for (let i = 0; i < uniqueBlockNumbers.length; i++) {\n const block = blocks[i];\n if (block) {\n timestamps.set(uniqueBlockNumbers[i], Number(block.timestamp));\n }\n }\n\n return timestamps;\n}\n\n/**\n * Suspend apps for an account\n */\nexport async function suspend(\n options: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n account: Address;\n apps: Address[];\n },\n logger: Logger,\n): Promise<Hex | false> {\n const { privateKey, rpcUrl, environmentConfig, account, apps } = options;\n\n const suspendData = encodeFunctionData({\n abi: AppControllerABI,\n functionName: \"suspend\",\n args: [account, apps],\n });\n\n const pendingMessage = `Suspending ${apps.length} app(s)...`;\n\n return sendAndWaitForTransaction(\n {\n privateKey,\n rpcUrl,\n environmentConfig,\n to: environmentConfig.appControllerAddress,\n data: suspendData,\n pendingMessage,\n txDescription: \"Suspend\",\n },\n logger,\n );\n}\n\n/**\n * Check if account is delegated to the ERC-7702 delegator\n */\nexport async function isDelegated(options: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n}): Promise<boolean> {\n const { privateKey, rpcUrl, environmentConfig } = options;\n\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n return checkERC7702Delegation(\n publicClient,\n account.address,\n environmentConfig.erc7702DelegatorAddress as Address,\n );\n}\n\n/**\n * Undelegate account (removes EIP-7702 delegation)\n */\nexport async function undelegate(\n options: {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n },\n logger: Logger,\n): Promise<Hex> {\n const { privateKey, rpcUrl, environmentConfig } = options;\n\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n\n const chain = getChainFromID(environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n // Create authorization to undelegate (empty address = undelegate)\n const transactionNonce = await publicClient.getTransactionCount({\n address: account.address,\n blockTag: \"pending\",\n });\n\n const chainId = await publicClient.getChainId();\n const authorizationNonce = BigInt(transactionNonce) + 1n;\n\n const authorization = {\n chainId: Number(chainId),\n address: \"0x0000000000000000000000000000000000000000\" as Address, // Empty address = undelegate\n nonce: authorizationNonce,\n };\n\n const sighash = hashAuthorization({\n chainId: authorization.chainId,\n contractAddress: authorization.address,\n nonce: Number(authorization.nonce),\n });\n\n const sig = await sign({\n hash: sighash,\n privateKey: privateKeyHex,\n });\n\n const v = Number(sig.v);\n const yParity = v === 27 ? 0 : 1;\n\n const authorizationList = [\n {\n chainId: authorization.chainId,\n address: authorization.address,\n nonce: Number(authorization.nonce),\n r: sig.r as Hex,\n s: sig.s as Hex,\n yParity,\n },\n ];\n\n // Send transaction with authorization list\n const hash = await walletClient.sendTransaction({\n account,\n to: account.address, // Send to self\n data: \"0x\" as Hex, // Empty data\n value: 0n,\n authorizationList,\n });\n\n logger.info(`Transaction sent: ${hash}`);\n\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status === \"reverted\") {\n logger.error(`Undelegate transaction (hash: ${hash}) reverted`);\n throw new Error(`Undelegate transaction (hash: ${hash}) reverted`);\n }\n\n return hash;\n}\n","/**\n * EIP-7702 transaction handling\n *\n * This module handles EIP-7702 delegation and batch execution\n */\n\nimport {\n Address,\n Hex,\n encodeFunctionData,\n encodeAbiParameters,\n decodeErrorResult,\n keccak256,\n toBytes,\n concat,\n} from \"viem\";\n\nimport type { WalletClient, PublicClient, SendTransactionParameters } from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\n\nimport ERC7702DelegatorABI from \"../abis/ERC7702Delegator.json\";\n\nimport { GasEstimate, formatETH } from \"./caller\";\n\n/**\n * Options for estimating batch gas\n */\nexport interface EstimateBatchGasOptions {\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }>;\n}\n\n/**\n * Estimate gas cost for a batch transaction\n *\n * Use this to get cost estimate before prompting user for confirmation.\n * Note: This provides a conservative estimate since batch transactions\n * through EIP-7702 can have variable costs.\n */\nexport async function estimateBatchGas(options: EstimateBatchGasOptions): Promise<GasEstimate> {\n const { publicClient, executions } = options;\n\n // Get current gas prices\n const fees = await publicClient.estimateFeesPerGas();\n\n // For batch operations, we use a conservative estimate\n // Each execution adds ~50k gas, plus base cost of ~100k for the delegator call\n const baseGas = 100000n;\n const perExecutionGas = 50000n;\n const estimatedGas = baseGas + BigInt(executions.length) * perExecutionGas;\n\n // Add 20% buffer for safety\n const gasLimit = (estimatedGas * 120n) / 100n;\n\n const maxFeePerGas = fees.maxFeePerGas;\n const maxPriorityFeePerGas = fees.maxPriorityFeePerGas;\n const maxCostWei = gasLimit * maxFeePerGas;\n const maxCostEth = formatETH(maxCostWei);\n\n return {\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas,\n maxCostWei,\n maxCostEth,\n };\n}\n\nexport interface ExecuteBatchOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n executions: Array<{\n target: Address;\n value: bigint;\n callData: Hex;\n }>;\n pendingMessage: string;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n}\n\n/**\n * Check if account is delegated to ERC-7702 delegator\n */\nexport async function checkERC7702Delegation(\n publicClient: PublicClient,\n account: Address,\n delegatorAddress: Address,\n): Promise<boolean> {\n const code = await publicClient.getBytecode({ address: account });\n if (!code) {\n return false;\n }\n\n // Check if code matches EIP-7702 delegation pattern: 0xef0100 || delegator_address\n const expectedCode = `0xef0100${delegatorAddress.slice(2)}`;\n return code.toLowerCase() === expectedCode.toLowerCase();\n}\n\n/**\n * Execute batch of operations via EIP-7702 delegator\n *\n * This function uses viem's built-in EIP-7702 support to handle transaction\n * construction, signing, and sending. We focus on:\n * 1. Encoding the executions correctly\n * 2. Creating authorization if needed\n * 3. Passing the right parameters to viem\n */\nexport async function executeBatch(options: ExecuteBatchOptions, logger: Logger): Promise<Hex> {\n const { walletClient, publicClient, environmentConfig, executions, pendingMessage, gas } =\n options;\n\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"Wallet client must have an account\");\n }\n\n const chain = walletClient.chain;\n if (!chain) {\n throw new Error(\"Wallet client must have a chain\");\n }\n\n // 1. Encode executions array\n // The Execution struct is: { target: address, value: uint256, callData: bytes }\n // Go's EncodeExecutions uses abi.Arguments.Pack which produces standard ABI encoding\n const encodedExecutions = encodeAbiParameters(\n [\n {\n type: \"tuple[]\",\n components: [\n { name: \"target\", type: \"address\" },\n { name: \"value\", type: \"uint256\" },\n { name: \"callData\", type: \"bytes\" },\n ],\n },\n ],\n [executions],\n );\n\n // 2. Pack ExecuteBatch call\n // Mode 0x01 is executeBatchMode (32 bytes, padded) (big endian)\n const executeBatchMode =\n \"0x0100000000000000000000000000000000000000000000000000000000000000\" as Hex;\n\n // Encode the execute function call\n // Function signature: execute(bytes32 _mode, bytes _executionCalldata)\n // Function selector: 0xe9ae5c53\n let executeBatchData: Hex;\n try {\n executeBatchData = encodeFunctionData({\n abi: ERC7702DelegatorABI,\n functionName: \"execute\",\n args: [executeBatchMode, encodedExecutions],\n });\n } catch {\n // Fallback: Manually construct if viem selects wrong overload\n const functionSignature = \"execute(bytes32,bytes)\";\n const selector = keccak256(toBytes(functionSignature)).slice(0, 10) as Hex;\n const encodedParams = encodeAbiParameters(\n [{ type: \"bytes32\" }, { type: \"bytes\" }],\n [executeBatchMode, encodedExecutions],\n );\n executeBatchData = concat([selector as Hex, encodedParams]) as Hex;\n }\n\n // 3. Check if account is delegated\n const isDelegated = await checkERC7702Delegation(\n publicClient,\n account.address,\n environmentConfig.erc7702DelegatorAddress as Address,\n );\n\n // 4. Create authorization if needed\n let authorizationList: Awaited<ReturnType<typeof walletClient.signAuthorization>>[] = [];\n\n if (!isDelegated) {\n const transactionNonce = await publicClient.getTransactionCount({\n address: account.address,\n blockTag: \"pending\",\n });\n\n const chainId = await publicClient.getChainId();\n const authorizationNonce = transactionNonce + 1;\n\n const signedAuthorization = await walletClient.signAuthorization({\n account,\n contractAddress: environmentConfig.erc7702DelegatorAddress as Address,\n chainId: Number(chainId),\n nonce: authorizationNonce,\n });\n\n authorizationList = [signedAuthorization];\n }\n\n // 5. Show pending message\n if (pendingMessage) {\n logger.info(pendingMessage);\n }\n\n const txRequest: SendTransactionParameters = {\n account: walletClient.account!,\n chain,\n to: account.address,\n data: executeBatchData,\n value: 0n,\n };\n\n if (authorizationList.length > 0) {\n txRequest.authorizationList = authorizationList;\n }\n\n // Add gas params if provided\n if (gas?.maxFeePerGas) {\n txRequest.maxFeePerGas = gas.maxFeePerGas;\n }\n if (gas?.maxPriorityFeePerGas) {\n txRequest.maxPriorityFeePerGas = gas.maxPriorityFeePerGas;\n }\n\n const hash = await walletClient.sendTransaction(txRequest);\n logger.info(`Transaction sent: ${hash}`);\n\n const receipt = await publicClient.waitForTransactionReceipt({ hash });\n\n if (receipt.status === \"reverted\") {\n let revertReason = \"Unknown reason\";\n try {\n await publicClient.call({\n to: account.address,\n data: executeBatchData,\n account: account.address,\n });\n } catch (callError: any) {\n if (callError.data) {\n try {\n const decoded = decodeErrorResult({\n abi: ERC7702DelegatorABI,\n data: callError.data,\n });\n revertReason = `${decoded.errorName}: ${JSON.stringify(decoded.args)}`;\n } catch {\n revertReason = callError.message || \"Unknown reason\";\n }\n } else {\n revertReason = callError.message || \"Unknown reason\";\n }\n }\n throw new Error(`Transaction reverted: ${hash}. Reason: ${revertReason}`);\n }\n\n return hash;\n}\n","[\n {\n \"type\": \"constructor\",\n \"inputs\": [\n {\n \"name\": \"_delegationManager\",\n \"type\": \"address\",\n \"internalType\": \"contractIDelegationManager\"\n },\n {\n \"name\": \"_entryPoint\",\n \"type\": \"address\",\n \"internalType\": \"contractIEntryPoint\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"receive\",\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"DOMAIN_VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"NAME\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"PACKED_USER_OP_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"VERSION\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addDeposit\",\n \"inputs\": [],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"delegationManager\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIDelegationManager\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"disableDelegation\",\n \"inputs\": [\n {\n \"name\": \"_delegation\",\n \"type\": \"tuple\",\n \"internalType\": \"structDelegation\",\n \"components\": [\n {\n \"name\": \"delegate\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"delegator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"authority\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"caveats\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structCaveat[]\",\n \"components\": [\n {\n \"name\": \"enforcer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"terms\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"args\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n },\n {\n \"name\": \"salt\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"eip712Domain\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"fields\",\n \"type\": \"bytes1\",\n \"internalType\": \"bytes1\"\n },\n {\n \"name\": \"name\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n },\n {\n \"name\": \"version\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n },\n {\n \"name\": \"chainId\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"verifyingContract\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"salt\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"extensions\",\n \"type\": \"uint256[]\",\n \"internalType\": \"uint256[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"enableDelegation\",\n \"inputs\": [\n {\n \"name\": \"_delegation\",\n \"type\": \"tuple\",\n \"internalType\": \"structDelegation\",\n \"components\": [\n {\n \"name\": \"delegate\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"delegator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"authority\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"caveats\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structCaveat[]\",\n \"components\": [\n {\n \"name\": \"enforcer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"terms\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"args\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n },\n {\n \"name\": \"salt\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"entryPoint\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIEntryPoint\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"execute\",\n \"inputs\": [\n {\n \"name\": \"_execution\",\n \"type\": \"tuple\",\n \"internalType\": \"structExecution\",\n \"components\": [\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"value\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"execute\",\n \"inputs\": [\n {\n \"name\": \"_mode\",\n \"type\": \"bytes32\",\n \"internalType\": \"ModeCode\"\n },\n {\n \"name\": \"_executionCalldata\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"executeFromExecutor\",\n \"inputs\": [\n {\n \"name\": \"_mode\",\n \"type\": \"bytes32\",\n \"internalType\": \"ModeCode\"\n },\n {\n \"name\": \"_executionCalldata\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"returnData_\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n }\n ],\n \"stateMutability\": \"payable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getDeposit\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getDomainHash\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getNonce\",\n \"inputs\": [\n {\n \"name\": \"_key\",\n \"type\": \"uint192\",\n \"internalType\": \"uint192\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getNonce\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPackedUserOperationHash\",\n \"inputs\": [\n {\n \"name\": \"_userOp\",\n \"type\": \"tuple\",\n \"internalType\": \"structPackedUserOperation\",\n \"components\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"initCode\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"accountGasLimits\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"preVerificationGas\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"gasFees\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"paymasterAndData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPackedUserOperationTypedDataHash\",\n \"inputs\": [\n {\n \"name\": \"_userOp\",\n \"type\": \"tuple\",\n \"internalType\": \"structPackedUserOperation\",\n \"components\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"initCode\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"accountGasLimits\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"preVerificationGas\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"gasFees\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"paymasterAndData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isDelegationDisabled\",\n \"inputs\": [\n {\n \"name\": \"_delegationHash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isValidSignature\",\n \"inputs\": [\n {\n \"name\": \"_hash\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"_signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"magicValue_\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"onERC1155BatchReceived\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256[]\",\n \"internalType\": \"uint256[]\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256[]\",\n \"internalType\": \"uint256[]\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"onERC1155Received\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"onERC721Received\",\n \"inputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"redeemDelegations\",\n \"inputs\": [\n {\n \"name\": \"_permissionContexts\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n },\n {\n \"name\": \"_modes\",\n \"type\": \"bytes32[]\",\n \"internalType\": \"ModeCode[]\"\n },\n {\n \"name\": \"_executionCallDatas\",\n \"type\": \"bytes[]\",\n \"internalType\": \"bytes[]\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"supportsExecutionMode\",\n \"inputs\": [\n {\n \"name\": \"_mode\",\n \"type\": \"bytes32\",\n \"internalType\": \"ModeCode\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"supportsInterface\",\n \"inputs\": [\n {\n \"name\": \"_interfaceId\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"validateUserOp\",\n \"inputs\": [\n {\n \"name\": \"_userOp\",\n \"type\": \"tuple\",\n \"internalType\": \"structPackedUserOperation\",\n \"components\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"nonce\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"initCode\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"callData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"accountGasLimits\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"preVerificationGas\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"gasFees\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"paymasterAndData\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"signature\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n },\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"_missingAccountFunds\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"validationData_\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"withdrawDeposit\",\n \"inputs\": [\n {\n \"name\": \"_withdrawAddress\",\n \"type\": \"address\",\n \"internalType\": \"addresspayable\"\n },\n {\n \"name\": \"_withdrawAmount\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"event\",\n \"name\": \"EIP712DomainChanged\",\n \"inputs\": [],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"SentPrefund\",\n \"inputs\": [\n {\n \"name\": \"sender\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"amount\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"success\",\n \"type\": \"bool\",\n \"indexed\": false,\n \"internalType\": \"bool\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"SetDelegationManager\",\n \"inputs\": [\n {\n \"name\": \"newDelegationManager\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIDelegationManager\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"SetEntryPoint\",\n \"inputs\": [\n {\n \"name\": \"entryPoint\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIEntryPoint\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"TryExecuteUnsuccessful\",\n \"inputs\": [\n {\n \"name\": \"batchExecutionindex\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"result\",\n \"type\": \"bytes\",\n \"indexed\": false,\n \"internalType\": \"bytes\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"ECDSAInvalidSignature\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"ECDSAInvalidSignatureLength\",\n \"inputs\": [\n {\n \"name\": \"length\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"ECDSAInvalidSignatureS\",\n \"inputs\": [\n {\n \"name\": \"s\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"ExecutionFailed\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidEIP712NameLength\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidEIP712VersionLength\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidShortString\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotDelegationManager\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotEntryPoint\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotEntryPointOrSelf\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotSelf\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"StringTooLong\",\n \"inputs\": [\n {\n \"name\": \"str\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"UnauthorizedCallContext\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"UnsupportedCallType\",\n \"inputs\": [\n {\n \"name\": \"callType\",\n \"type\": \"bytes1\",\n \"internalType\": \"CallType\"\n }\n ]\n },\n {\n \"type\": \"error\",\n \"name\": \"UnsupportedExecType\",\n \"inputs\": [\n {\n \"name\": \"execType\",\n \"type\": \"bytes1\",\n \"internalType\": \"ExecType\"\n }\n ]\n }\n]\n","/**\n * Default logger\n */\n\nimport { Logger } from \"../types\";\n\nexport const defaultLogger: Logger = {\n info: (...args) => console.info(...args),\n warn: (...args) => console.warn(...args),\n error: (...args) => console.error(...args),\n debug: (...args) => console.debug(...args),\n};\n\nexport const getLogger: (verbose?: boolean) => Logger = (verbose?: boolean) => ({\n info: (...args) => console.info(...args),\n warn: (...args) => console.warn(...args),\n error: (...args) => console.error(...args),\n debug: (...args) => verbose && console.debug(...args),\n});\n","/**\n * UserAPI Client to manage interactions with the coordinator\n */\n\nimport axios, { AxiosResponse } from \"axios\";\nimport FormData from \"form-data\";\nimport { Address, Hex, createPublicClient, http } from \"viem\";\nimport { calculatePermissionSignature } from \"./auth\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { EnvironmentConfig } from \"../types\";\nimport { addHexPrefix, stripHexPrefix, getChainFromID } from \"./helpers\";\n\nexport interface AppProfileInfo {\n name: string;\n website?: string;\n description?: string;\n xURL?: string;\n imageURL?: string;\n}\n\nexport interface AppMetrics {\n cpu_utilization_percent?: number;\n memory_utilization_percent?: number;\n memory_used_bytes?: number;\n memory_total_bytes?: number;\n}\n\nexport interface DerivedAddress {\n address: string;\n derivationPath: string;\n}\n\nexport interface AppInfo {\n address: Address;\n status: string;\n ip: string;\n machineType: string;\n profile?: AppProfileInfo;\n metrics?: AppMetrics;\n evmAddresses: DerivedAddress[];\n solanaAddresses: DerivedAddress[];\n}\n\nexport interface AppInfoResponse {\n apps: Array<{\n addresses: {\n data: {\n evmAddresses: DerivedAddress[];\n solanaAddresses: DerivedAddress[];\n };\n signature: string;\n };\n app_status: string;\n ip: string;\n machine_type: string;\n profile?: AppProfileInfo;\n metrics?: AppMetrics;\n }>;\n}\n\nconst MAX_ADDRESS_COUNT = 5;\n\n// Permission constants\nexport const CanViewAppLogsPermission = \"0x2fd3f2fe\" as Hex;\nexport const CanViewSensitiveAppInfoPermission = \"0x0e67b22f\" as Hex;\nexport const CanUpdateAppProfilePermission = \"0x036fef61\" as Hex;\n\n/**\n * SDK_VERSION_BUILD_TIME is replaced at build time by tsup's define option\n */\n// @ts-ignore - SDK_VERSION_BUILD_TIME is injected at build time by tsup\ndeclare const SDK_VERSION_BUILD_TIME: string | undefined;\n\n/**\n * Get the default client ID using the build-time version\n */\nfunction getDefaultClientId(): string {\n // @ts-ignore - SDK_VERSION_BUILD_TIME is injected at build time\n const version = typeof SDK_VERSION_BUILD_TIME !== \"undefined\" ? SDK_VERSION_BUILD_TIME : \"0.0.0\";\n return `ecloud-sdk/v${version}`;\n}\n\nexport class UserApiClient {\n private readonly account?: ReturnType<typeof privateKeyToAccount>;\n private readonly rpcUrl?: string;\n private readonly clientId: string;\n\n constructor(\n private readonly config: EnvironmentConfig,\n privateKey?: string | Hex,\n rpcUrl?: string,\n clientId?: string,\n ) {\n if (privateKey) {\n const privateKeyHex = addHexPrefix(privateKey);\n this.account = privateKeyToAccount(privateKeyHex);\n }\n this.rpcUrl = rpcUrl;\n this.clientId = clientId || getDefaultClientId();\n }\n\n async getInfos(appIDs: Address[], addressCount = 1): Promise<AppInfo[]> {\n const count = Math.min(addressCount, MAX_ADDRESS_COUNT);\n\n const endpoint = `${this.config.userApiServerURL}/info`;\n const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(\",\") })}`;\n\n const res = await this.makeAuthenticatedRequest(url, CanViewSensitiveAppInfoPermission);\n const result: AppInfoResponse = await res.json();\n\n // optional: verify signatures with KMS key\n // const { signingKey } = getKMSKeysForEnvironment(this.config.name);\n\n // Truncate without mutating the original object\n // API returns apps in the same order as the request, so use appIDs[i] as the address\n return result.apps.map((app, i) => {\n // TODO: Implement signature verification\n // const valid = await verifyKMSSignature(appInfo.addresses, signingKey);\n // if (!valid) {\n // throw new Error(`Invalid signature for app ${appIDs[i]}`);\n // }\n\n // Slice derived addresses to requested count\n const evmAddresses = app.addresses?.data?.evmAddresses?.slice(0, count) || [];\n const solanaAddresses = app.addresses?.data?.solanaAddresses?.slice(0, count) || [];\n\n return {\n address: appIDs[i] as Address,\n status: app.app_status,\n ip: app.ip,\n machineType: app.machine_type,\n profile: app.profile,\n metrics: app.metrics,\n evmAddresses,\n solanaAddresses,\n };\n });\n }\n\n /**\n * Get available SKUs (instance types) from UserAPI\n */\n async getSKUs(): Promise<{\n skus: Array<{ sku: string; description: string }>;\n }> {\n const endpoint = `${this.config.userApiServerURL}/skus`;\n const response = await this.makeAuthenticatedRequest(endpoint);\n\n const result = await response.json();\n\n // Transform response to match expected format\n return {\n skus: result.skus || result.SKUs || [],\n };\n }\n\n /**\n * Get logs for an app\n */\n async getLogs(appID: Address): Promise<string> {\n const endpoint = `${this.config.userApiServerURL}/logs/${appID}`;\n const response = await this.makeAuthenticatedRequest(endpoint, CanViewAppLogsPermission);\n return await response.text();\n }\n\n /**\n * Get statuses for apps\n */\n async getStatuses(appIDs: Address[]): Promise<Array<{ address: Address; status: string }>> {\n const endpoint = `${this.config.userApiServerURL}/status`;\n const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(\",\") })}`;\n const response = await this.makeAuthenticatedRequest(url);\n const result = await response.json();\n\n // Transform response to match expected format\n // The API returns an array of app statuses\n const apps = result.apps || result.Apps || [];\n return apps.map((app: any, i: number) => ({\n address: (app.address || appIDs[i]) as Address,\n status: app.status || app.Status || \"\",\n }));\n }\n\n /**\n * Upload app profile information with optional image\n */\n async uploadAppProfile(\n appAddress: Address,\n name: string,\n website?: string,\n description?: string,\n xURL?: string,\n imagePath?: string,\n ): Promise<{\n name: string;\n website?: string;\n description?: string;\n xURL?: string;\n imageURL?: string;\n }> {\n const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}/profile`;\n\n // Build multipart form data using form-data package\n const formData = new FormData();\n\n // Add required name field\n formData.append(\"name\", name);\n\n // Add optional text fields\n if (website) {\n formData.append(\"website\", website);\n }\n if (description) {\n formData.append(\"description\", description);\n }\n if (xURL) {\n formData.append(\"xURL\", xURL);\n }\n\n // Add optional image file\n if (imagePath) {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const fileName = path.basename(imagePath);\n\n // Read file into buffer\n const fileBuffer = fs.readFileSync(imagePath);\n formData.append(\"image\", fileBuffer, fileName);\n }\n\n // Make authenticated POST request\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n ...formData.getHeaders(),\n };\n\n // Add auth headers (Authorization and X-eigenx-expiry)\n if (this.account) {\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60); // 5 minutes\n const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);\n Object.assign(headers, authHeaders);\n }\n\n try {\n // Use axios to post req\n const response: AxiosResponse = await axios.post(endpoint, formData, {\n headers,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n maxContentLength: Infinity, // Allow large file uploads\n maxBodyLength: Infinity, // Allow large file uploads\n });\n\n const status = response.status;\n\n if (status !== 200 && status !== 201) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n\n // Detect Cloudflare challenge page\n if (status === 403 && body.includes(\"Cloudflare\") && body.includes(\"challenge-platform\")) {\n throw new Error(\n `Cloudflare protection is blocking the request. This is likely due to bot detection.\\n` +\n `Status: ${status}`,\n );\n }\n\n throw new Error(\n `UserAPI request failed: ${status} ${status >= 200 && status < 300 ? \"OK\" : \"Error\"} - ${body.substring(0, 500)}${body.length > 500 ? \"...\" : \"\"}`,\n );\n }\n\n return response.data;\n } catch (error: any) {\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to UserAPI at ${endpoint}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.userApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n throw error;\n }\n }\n\n private async makeAuthenticatedRequest(\n url: string,\n permission?: Hex,\n ): Promise<{ json: () => Promise<any>; text: () => Promise<string> }> {\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n };\n // Add auth headers if permission is specified\n if (permission && this.account) {\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60); // 5 minutes\n const authHeaders = await this.generateAuthHeaders(permission, expiry);\n Object.assign(headers, authHeaders);\n }\n\n try {\n // Use axios to match\n const response: AxiosResponse = await axios.get(url, {\n headers,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n });\n\n const status = response.status;\n const statusText = status >= 200 && status < 300 ? \"OK\" : \"Error\";\n\n if (status < 200 || status >= 300) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n throw new Error(`UserAPI request failed: ${status} ${statusText} - ${body}`);\n }\n\n // Return Response-like object for compatibility\n return {\n json: async () => response.data,\n text: async () =>\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data),\n };\n } catch (error: any) {\n // Handle network errors (fetch failed, connection refused, etc.)\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to UserAPI at ${url}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.userApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n // Re-throw other errors as-is\n throw error;\n }\n }\n\n /**\n * Generate authentication headers for UserAPI requests\n */\n private async generateAuthHeaders(\n permission: Hex,\n expiry: bigint,\n ): Promise<Record<string, string>> {\n if (!this.account) {\n throw new Error(\"Private key required for authenticated requests\");\n }\n\n if (!this.rpcUrl) {\n throw new Error(\"RPC URL required for authenticated requests\");\n }\n\n const chain = getChainFromID(this.config.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(this.rpcUrl),\n });\n\n // Calculate permission signature using shared auth utility\n const { signature } = await calculatePermissionSignature({\n permission,\n expiry,\n appControllerAddress: this.config.appControllerAddress,\n publicClient,\n account: this.account,\n });\n\n // Return auth headers\n return {\n Authorization: `Bearer ${stripHexPrefix(signature)}`,\n \"X-eigenx-expiry\": expiry.toString(),\n };\n }\n}\n","/**\n * Shared authentication utilities for API clients\n */\n\nimport { Hex, parseAbi, type Address } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { createPublicClient } from \"viem\";\n\n// Minimal AppController ABI for permission calculation\nconst APP_CONTROLLER_ABI = parseAbi([\n \"function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) view returns (bytes32)\",\n]);\n\nexport interface PermissionSignatureOptions {\n permission: Hex;\n expiry: bigint;\n appControllerAddress: Address;\n publicClient: ReturnType<typeof createPublicClient>;\n account: ReturnType<typeof privateKeyToAccount>;\n}\n\nexport interface PermissionSignatureResult {\n signature: string;\n digest: Hex;\n}\n\n/**\n * Calculate permission digest via AppController contract and sign it with EIP-191\n */\nexport async function calculatePermissionSignature(\n options: PermissionSignatureOptions,\n): Promise<PermissionSignatureResult> {\n const { permission, expiry, appControllerAddress, publicClient, account } = options;\n\n // Calculate permission digest hash using AppController contract\n const digest = (await publicClient.readContract({\n address: appControllerAddress,\n abi: APP_CONTROLLER_ABI,\n functionName: \"calculateApiPermissionDigestHash\",\n args: [permission, expiry],\n })) as Hex;\n\n // Sign the digest using EIP-191 (signMessage handles prefixing automatically)\n const signature = await account.signMessage({\n message: { raw: digest },\n });\n\n return { signature, digest };\n}\n\nexport interface BillingAuthSignatureOptions {\n account: ReturnType<typeof privateKeyToAccount>;\n product: string;\n expiry: bigint;\n}\n\nexport interface BillingAuthSignatureResult {\n signature: Hex;\n expiry: bigint;\n}\n\n/**\n * Sign billing authentication message using EIP-712 typed data\n */\nexport async function calculateBillingAuthSignature(\n options: BillingAuthSignatureOptions,\n): Promise<BillingAuthSignatureResult> {\n const { account, product, expiry } = options;\n\n // Sign using EIP-712 typed data\n const signature = await account.signTypedData({\n domain: {\n name: \"EigenCloud Billing API\",\n version: \"1\",\n },\n types: {\n BillingAuth: [\n { name: \"product\", type: \"string\" },\n { name: \"expiry\", type: \"uint256\" },\n ],\n },\n primaryType: \"BillingAuth\",\n message: {\n product,\n expiry,\n },\n });\n\n return { signature, expiry };\n}\n","/**\n * General utility helpers\n */\n\nimport { extractChain } from \"viem\";\nimport type { Chain, Hex } from \"viem\";\nimport { sepolia } from \"viem/chains\";\nimport { SUPPORTED_CHAINS } from \"../constants\";\n\n/**\n * Get a viem Chain object from a chain ID.\n * Supports mainnet (1) and sepolia (11155111), defaults to the fallback chain for unknown chains.\n */\nexport function getChainFromID(chainID: bigint, fallback: Chain = sepolia): Chain {\n const id = Number(chainID) as (typeof SUPPORTED_CHAINS)[number][\"id\"];\n return extractChain({ chains: SUPPORTED_CHAINS, id }) || fallback;\n}\n\n/**\n * Ensure hex string has 0x prefix\n */\nexport function addHexPrefix(value: string): Hex {\n return (value.startsWith(\"0x\") ? value : `0x${value}`) as Hex;\n}\n\n/**\n * Remove 0x prefix from hex string if present\n */\nexport function stripHexPrefix(value: string): string {\n return value.startsWith(\"0x\") ? value.slice(2) : value;\n}\n","[\n {\n \"type\": \"constructor\",\n \"inputs\": [\n {\n \"name\": \"_version\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n },\n {\n \"name\": \"_permissionController\",\n \"type\": \"address\",\n \"internalType\": \"contractIPermissionController\"\n },\n {\n \"name\": \"_releaseManager\",\n \"type\": \"address\",\n \"internalType\": \"contractIReleaseManager\"\n },\n {\n \"name\": \"_computeAVSRegistrar\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeAVSRegistrar\"\n },\n {\n \"name\": \"_computeOperator\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeOperator\"\n },\n {\n \"name\": \"_appBeacon\",\n \"type\": \"address\",\n \"internalType\": \"contractIBeacon\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"API_PERMISSION_TYPEHASH\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"appBeacon\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIBeacon\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"calculateApiPermissionDigestHash\",\n \"inputs\": [\n {\n \"name\": \"permission\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n },\n {\n \"name\": \"expiry\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"calculateAppId\",\n \"inputs\": [\n {\n \"name\": \"deployer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"salt\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"computeAVSRegistrar\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeAVSRegistrar\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"computeOperator\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIComputeOperator\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"createApp\",\n \"inputs\": [\n {\n \"name\": \"salt\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"release\",\n \"type\": \"tuple\",\n \"internalType\": \"structIAppController.Release\",\n \"components\": [\n {\n \"name\": \"rmsRelease\",\n \"type\": \"tuple\",\n \"internalType\": \"structIReleaseManagerTypes.Release\",\n \"components\": [\n {\n \"name\": \"artifacts\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIReleaseManagerTypes.Artifact[]\",\n \"components\": [\n {\n \"name\": \"digest\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"registry\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"name\": \"upgradeByTime\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ]\n },\n {\n \"name\": \"publicEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"encryptedEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"domainSeparator\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getActiveAppCount\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppCreator\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppLatestReleaseBlockNumber\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppOperatorSetId\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppStatus\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getApps\",\n \"inputs\": [\n {\n \"name\": \"offset\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n },\n {\n \"name\": \"appConfigsMem\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIAppController.AppConfig[]\",\n \"components\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"latestReleaseBlockNumber\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"status\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppsByCreator\",\n \"inputs\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"offset\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n },\n {\n \"name\": \"appConfigsMem\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIAppController.AppConfig[]\",\n \"components\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"latestReleaseBlockNumber\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"status\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppsByDeveloper\",\n \"inputs\": [\n {\n \"name\": \"developer\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"offset\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n },\n {\n \"name\": \"appConfigsMem\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIAppController.AppConfig[]\",\n \"components\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"latestReleaseBlockNumber\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n },\n {\n \"name\": \"status\",\n \"type\": \"uint8\",\n \"internalType\": \"enumIAppController.AppStatus\"\n }\n ]\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getMaxActiveAppsPerUser\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"globalActiveAppCount\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"initialize\",\n \"inputs\": [\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"maxGlobalActiveApps\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"permissionController\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIPermissionController\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"releaseManager\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address\",\n \"internalType\": \"contractIReleaseManager\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setMaxActiveAppsPerUser\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setMaxGlobalActiveApps\",\n \"inputs\": [\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"startApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"stopApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"suspend\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"apps\",\n \"type\": \"address[]\",\n \"internalType\": \"contractIApp[]\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"terminateApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"terminateAppByAdmin\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"updateAppMetadataURI\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"metadataURI\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"upgradeApp\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"release\",\n \"type\": \"tuple\",\n \"internalType\": \"structIAppController.Release\",\n \"components\": [\n {\n \"name\": \"rmsRelease\",\n \"type\": \"tuple\",\n \"internalType\": \"structIReleaseManagerTypes.Release\",\n \"components\": [\n {\n \"name\": \"artifacts\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIReleaseManagerTypes.Artifact[]\",\n \"components\": [\n {\n \"name\": \"digest\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"registry\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"name\": \"upgradeByTime\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ]\n },\n {\n \"name\": \"publicEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"encryptedEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"uint256\",\n \"internalType\": \"uint256\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"version\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"event\",\n \"name\": \"AppCreated\",\n \"inputs\": [\n {\n \"name\": \"creator\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"operatorSetId\",\n \"type\": \"uint32\",\n \"indexed\": false,\n \"internalType\": \"uint32\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppMetadataURIUpdated\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"metadataURI\",\n \"type\": \"string\",\n \"indexed\": false,\n \"internalType\": \"string\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppStarted\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppStopped\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppSuspended\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppTerminated\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppTerminatedByAdmin\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppUpgraded\",\n \"inputs\": [\n {\n \"name\": \"app\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"contractIApp\"\n },\n {\n \"name\": \"rmsReleaseId\",\n \"type\": \"uint256\",\n \"indexed\": false,\n \"internalType\": \"uint256\"\n },\n {\n \"name\": \"release\",\n \"type\": \"tuple\",\n \"indexed\": false,\n \"internalType\": \"structIAppController.Release\",\n \"components\": [\n {\n \"name\": \"rmsRelease\",\n \"type\": \"tuple\",\n \"internalType\": \"structIReleaseManagerTypes.Release\",\n \"components\": [\n {\n \"name\": \"artifacts\",\n \"type\": \"tuple[]\",\n \"internalType\": \"structIReleaseManagerTypes.Artifact[]\",\n \"components\": [\n {\n \"name\": \"digest\",\n \"type\": \"bytes32\",\n \"internalType\": \"bytes32\"\n },\n {\n \"name\": \"registry\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n },\n {\n \"name\": \"upgradeByTime\",\n \"type\": \"uint32\",\n \"internalType\": \"uint32\"\n }\n ]\n },\n {\n \"name\": \"publicEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n },\n {\n \"name\": \"encryptedEnv\",\n \"type\": \"bytes\",\n \"internalType\": \"bytes\"\n }\n ]\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"GlobalMaxActiveAppsSet\",\n \"inputs\": [\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"indexed\": false,\n \"internalType\": \"uint32\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"Initialized\",\n \"inputs\": [\n {\n \"name\": \"version\",\n \"type\": \"uint8\",\n \"indexed\": false,\n \"internalType\": \"uint8\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"MaxActiveAppsSet\",\n \"inputs\": [\n {\n \"name\": \"user\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"limit\",\n \"type\": \"uint32\",\n \"indexed\": false,\n \"internalType\": \"uint32\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"AccountHasActiveApps\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppAlreadyExists\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppDoesNotExist\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"GlobalMaxActiveAppsExceeded\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidAppStatus\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidPermissions\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidReleaseMetadataURI\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidShortString\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"InvalidSignature\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"MaxActiveAppsExceeded\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"MoreThanOneArtifact\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"SignatureExpired\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"StringTooLong\",\n \"inputs\": [\n {\n \"name\": \"str\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ]\n }\n]\n","[\n {\n \"type\": \"function\",\n \"name\": \"acceptAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"addPendingAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"canCall\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"caller\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAdmins\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppointeePermissions\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n },\n {\n \"name\": \"\",\n \"type\": \"bytes4[]\",\n \"internalType\": \"bytes4[]\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getAppointees\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"getPendingAdmins\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"address[]\",\n \"internalType\": \"address[]\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"caller\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"isPendingAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"pendingAdmin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"bool\",\n \"internalType\": \"bool\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"function\",\n \"name\": \"removeAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"removeAppointee\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"removePendingAdmin\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"setAppointee\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"internalType\": \"bytes4\"\n }\n ],\n \"outputs\": [],\n \"stateMutability\": \"nonpayable\"\n },\n {\n \"type\": \"function\",\n \"name\": \"version\",\n \"inputs\": [],\n \"outputs\": [\n {\n \"name\": \"\",\n \"type\": \"string\",\n \"internalType\": \"string\"\n }\n ],\n \"stateMutability\": \"view\"\n },\n {\n \"type\": \"event\",\n \"name\": \"AdminRemoved\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AdminSet\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppointeeRemoved\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"indexed\": false,\n \"internalType\": \"bytes4\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"AppointeeSet\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"appointee\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"target\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"selector\",\n \"type\": \"bytes4\",\n \"indexed\": false,\n \"internalType\": \"bytes4\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"PendingAdminAdded\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"event\",\n \"name\": \"PendingAdminRemoved\",\n \"inputs\": [\n {\n \"name\": \"account\",\n \"type\": \"address\",\n \"indexed\": true,\n \"internalType\": \"address\"\n },\n {\n \"name\": \"admin\",\n \"type\": \"address\",\n \"indexed\": false,\n \"internalType\": \"address\"\n }\n ],\n \"anonymous\": false\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminAlreadyPending\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminAlreadySet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminNotPending\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AdminNotSet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppointeeAlreadySet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"AppointeeNotSet\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"CannotHaveZeroAdmins\",\n \"inputs\": []\n },\n {\n \"type\": \"error\",\n \"name\": \"NotAdmin\",\n \"inputs\": []\n }\n]\n","/**\n * Contract watcher\n *\n * Watches app status until it reaches Running state using UserAPI\n */\n\nimport { Address } from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\nimport { UserApiClient } from \"../utils/userapi\";\n\nexport interface WatchUntilRunningOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n clientId?: string;\n}\n\nconst WATCH_POLL_INTERVAL_SECONDS = 5;\nconst APP_STATUS_RUNNING = \"Running\";\nconst APP_STATUS_FAILED = \"Failed\";\n// const APP_STATUS_DEPLOYING = 'Deploying';\n\n/**\n * Watch app until it reaches Running status with IP address\n */\nexport async function watchUntilRunning(\n options: WatchUntilRunningOptions,\n logger: Logger,\n): Promise<string | undefined> {\n const { environmentConfig, appId, privateKey, rpcUrl, clientId } = options;\n\n // Create UserAPI client\n const userApiClient = new UserApiClient(environmentConfig, privateKey, rpcUrl, clientId);\n\n // Track initial status and whether we've seen a change\n let initialStatus: string | undefined;\n let initialIP: string | undefined;\n let hasChanged = false;\n\n // Stop condition: Running status with IP (but only after seeing a change if starting from Running)\n const stopCondition = (status: string, ip: string): boolean => {\n // Capture initial state on first call\n if (!initialStatus) {\n initialStatus = status;\n initialIP = ip;\n }\n\n // Track if status has changed from initial\n if (status !== initialStatus) {\n hasChanged = true;\n }\n\n // Exit on Running with IP, but only if:\n // - We've seen a status change (handles upgrades), OR\n // - Initial status was not Running (handles fresh deploys)\n if (status === APP_STATUS_RUNNING && ip) {\n if (hasChanged || initialStatus !== APP_STATUS_RUNNING) {\n // Only log IP if we didn't have one initially\n if (!initialIP || initialIP === \"No IP assigned\") {\n logger.info(`App is now running with IP: ${ip}`);\n } else {\n logger.info(\"App is now running\");\n }\n return true;\n }\n }\n\n // Check for failure states\n if (status === APP_STATUS_FAILED) {\n throw new Error(`App entered ${status} state`);\n }\n\n return false;\n };\n\n // Main watch loop\n while (true) {\n try {\n // Fetch app info\n const info = await userApiClient.getInfos([appId], 1);\n if (info.length === 0) {\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n continue;\n }\n\n const appInfo = info[0];\n const currentStatus = appInfo.status;\n const currentIP = appInfo.ip || \"\";\n\n // Check stop condition\n if (stopCondition(currentStatus, currentIP)) {\n return currentIP || undefined;\n }\n\n // Wait before next poll\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n } catch (error: any) {\n logger.warn(`Failed to fetch app info: ${error.message}`);\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n }\n }\n}\n\nexport interface WatchUntilUpgradeCompleteOptions {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n appId: Address;\n clientId?: string;\n}\n\nconst APP_STATUS_STOPPED = \"Stopped\";\n\n/**\n * Watch app until upgrade completes\n * For upgrades, we watch until the app reaches Stopped status (upgrade complete)\n * or Running status (if it was running before upgrade)\n */\nexport async function watchUntilUpgradeComplete(\n options: WatchUntilUpgradeCompleteOptions,\n logger: Logger,\n): Promise<void> {\n const { environmentConfig, appId, privateKey, rpcUrl, clientId } = options;\n\n // Create UserAPI client\n const userApiClient = new UserApiClient(environmentConfig, privateKey, rpcUrl, clientId);\n\n // Track initial status and whether we've seen a change\n let initialStatus: string | undefined;\n let initialIP: string | undefined;\n let hasChanged = false;\n\n // Stop condition: Watch for upgrade completion\n const stopCondition = (status: string, ip: string): boolean => {\n // Capture initial state on first call\n if (!initialStatus) {\n initialStatus = status;\n initialIP = ip;\n\n // If app is already stopped with IP, upgrade is complete\n if (status === APP_STATUS_STOPPED && ip) {\n logger.info(\"App upgrade complete.\");\n logger.info(`Status: ${status}`);\n logger.info(`To start the app, run: ecloud compute app start ${appId}`);\n return true;\n }\n }\n\n // Track if status has changed from initial\n if (status !== initialStatus) {\n hasChanged = true;\n }\n\n // Exit on Stopped status with IP after seeing a change (upgrade complete)\n if (status === APP_STATUS_STOPPED && ip && hasChanged) {\n logger.info(\"App upgrade complete.\");\n logger.info(`Status: ${status}`);\n logger.info(`To start the app, run: ecloud compute app start ${appId}`);\n return true;\n }\n\n // Exit on Running status with IP after seeing a change (upgrade complete and app restarted)\n if (status === APP_STATUS_RUNNING && ip && hasChanged) {\n if (!initialIP || initialIP === \"No IP assigned\") {\n logger.info(`App is now running with IP: ${ip}`);\n } else {\n logger.info(\"App is now running\");\n }\n return true;\n }\n\n // Check for failure states\n if (status === APP_STATUS_FAILED) {\n throw new Error(`App entered ${status} state`);\n }\n\n return false;\n };\n\n // Main watch loop\n while (true) {\n try {\n // Fetch app info\n const info = await userApiClient.getInfos([appId], 1);\n if (info.length === 0) {\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n continue;\n }\n\n const appInfo = info[0];\n const currentStatus = appInfo.status;\n const currentIP = appInfo.ip || \"\";\n\n // Check stop condition\n if (stopCondition(currentStatus, currentIP)) {\n return;\n }\n\n // Wait before next poll\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n } catch (error: any) {\n logger.warn(`Failed to fetch app info: ${error.message}`);\n await sleep(WATCH_POLL_INTERVAL_SECONDS * 1000);\n }\n }\n}\n\n/**\n * Sleep utility\n */\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","/**\n * Non-interactive validation utilities for SDK\n *\n * These functions validate parameters without any interactive prompts.\n * They either return the validated value or throw an error.\n */\n\nimport fs from \"fs\";\nimport path from \"path\";\nimport { Address, isAddress } from \"viem\";\nimport { stripHexPrefix, addHexPrefix } from \"./helpers\";\n\n// ==================== App Name Validation ====================\n\n/**\n * Validate app name format\n * @throws Error if name is invalid\n */\nexport function validateAppName(name: string): void {\n if (!name) {\n throw new Error(\"App name cannot be empty\");\n }\n if (name.includes(\" \")) {\n throw new Error(\"App name cannot contain spaces\");\n }\n if (name.length > 50) {\n throw new Error(\"App name cannot be longer than 50 characters\");\n }\n}\n\n// ==================== Image Reference Validation ====================\n\n/**\n * Validate Docker image reference format\n * @returns true if valid, error message string if invalid\n */\nexport function validateImageReference(value: string): true | string {\n if (!value) {\n return \"Image reference cannot be empty\";\n }\n // Basic validation - should contain at least one / and optionally :\n if (!value.includes(\"/\")) {\n return \"Image reference must contain at least one /\";\n }\n return true;\n}\n\n/**\n * Validate image reference and throw if invalid\n * @throws Error if image reference is invalid\n */\nexport function assertValidImageReference(value: string): void {\n const result = validateImageReference(value);\n if (result !== true) {\n throw new Error(result);\n }\n}\n\n/**\n * Extract app name from image reference\n */\nexport function extractAppNameFromImage(imageRef: string): string {\n // Remove registry prefix if present\n const parts = imageRef.split(\"/\");\n let imageName = parts.length > 1 ? parts[parts.length - 1] : imageRef;\n\n // Split image and tag\n if (imageName.includes(\":\")) {\n imageName = imageName.split(\":\")[0];\n }\n\n return imageName;\n}\n\n// ==================== File Path Validation ====================\n\n/**\n * Validate that a file path exists\n * @returns true if valid, error message string if invalid\n */\nexport function validateFilePath(value: string): true | string {\n if (!value) {\n return \"File path cannot be empty\";\n }\n if (!fs.existsSync(value)) {\n return \"File does not exist\";\n }\n return true;\n}\n\n/**\n * Validate file path and throw if invalid\n * @throws Error if file path is invalid or doesn't exist\n */\nexport function assertValidFilePath(value: string): void {\n const result = validateFilePath(value);\n if (result !== true) {\n throw new Error(result);\n }\n}\n\n// ==================== Instance Type Validation ====================\n\n/**\n * Validate instance type SKU against available types\n * @returns the validated SKU\n * @throws Error if SKU is not in the available types list\n */\nexport function validateInstanceTypeSKU(\n sku: string,\n availableTypes: Array<{ sku: string }>,\n): string {\n if (!sku) {\n throw new Error(\"Instance type SKU cannot be empty\");\n }\n\n // Check if SKU is valid\n for (const it of availableTypes) {\n if (it.sku === sku) {\n return sku;\n }\n }\n\n // Build helpful error message with valid options\n const validSKUs = availableTypes.map((it) => it.sku).join(\", \");\n throw new Error(`Invalid instance-type value: ${sku} (must be one of: ${validSKUs})`);\n}\n\n// ==================== Private Key Validation ====================\n\n/**\n * Validate private key format\n * Matches Go's common.ValidatePrivateKey() function\n */\nexport function validatePrivateKeyFormat(key: string): boolean {\n // Remove 0x prefix if present\n const keyWithoutPrefix = stripHexPrefix(key);\n\n // Must be 64 hex characters (32 bytes)\n if (!/^[0-9a-fA-F]{64}$/.test(keyWithoutPrefix)) {\n return false;\n }\n\n return true;\n}\n\n/**\n * Validate private key and throw if invalid\n * @throws Error if private key format is invalid\n */\nexport function assertValidPrivateKey(key: string): void {\n if (!key) {\n throw new Error(\"Private key is required\");\n }\n if (!validatePrivateKeyFormat(key)) {\n throw new Error(\n \"Invalid private key format (must be 64 hex characters, optionally prefixed with 0x)\",\n );\n }\n}\n\n// ==================== URL Validation ====================\n\n/**\n * Validate URL format\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateURL(rawURL: string): string | undefined {\n if (!rawURL.trim()) {\n return \"URL cannot be empty\";\n }\n\n try {\n const url = new URL(rawURL);\n if (url.protocol !== \"http:\" && url.protocol !== \"https:\") {\n return \"URL scheme must be http or https\";\n }\n } catch {\n return \"Invalid URL format\";\n }\n\n return undefined;\n}\n\n/**\n * Valid X/Twitter hosts\n */\nconst VALID_X_HOSTS = [\"twitter.com\", \"www.twitter.com\", \"x.com\", \"www.x.com\"];\n\n/**\n * Validate X/Twitter URL format\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateXURL(rawURL: string): string | undefined {\n // First validate as URL\n const urlErr = validateURL(rawURL);\n if (urlErr) {\n return urlErr;\n }\n\n try {\n const url = new URL(rawURL);\n const host = url.hostname.toLowerCase();\n\n // Accept twitter.com and x.com domains\n if (!VALID_X_HOSTS.includes(host)) {\n return \"URL must be a valid X/Twitter URL (x.com or twitter.com)\";\n }\n\n // Ensure it has a path (username/profile)\n if (!url.pathname || url.pathname === \"/\") {\n return \"X URL must include a username or profile path\";\n }\n } catch {\n return \"Invalid X URL format\";\n }\n\n return undefined;\n}\n\n// ==================== Description Validation ====================\n\nconst MAX_DESCRIPTION_LENGTH = 1000;\n\n/**\n * Validate description length\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateDescription(description: string): string | undefined {\n if (!description.trim()) {\n return \"Description cannot be empty\";\n }\n\n if (description.length > MAX_DESCRIPTION_LENGTH) {\n return `Description cannot exceed ${MAX_DESCRIPTION_LENGTH} characters`;\n }\n\n return undefined;\n}\n\n// ==================== Image Path Validation ====================\n\nconst MAX_IMAGE_SIZE = 4 * 1024 * 1024; // 4MB\nconst VALID_IMAGE_EXTENSIONS = [\".jpg\", \".jpeg\", \".png\"];\n\n/**\n * Validate image file path\n * @returns undefined if valid, error message string if invalid\n */\nexport function validateImagePath(filePath: string): string | undefined {\n // Strip quotes that may be added by terminal drag-and-drop\n const cleanedPath = filePath.trim().replace(/^[\"']|[\"']$/g, \"\");\n\n if (!cleanedPath) {\n return \"Image path cannot be empty\";\n }\n\n // Check if file exists\n if (!fs.existsSync(cleanedPath)) {\n return `Image file not found: ${cleanedPath}`;\n }\n\n const stats = fs.statSync(cleanedPath);\n if (stats.isDirectory()) {\n return \"Path is a directory, not a file\";\n }\n\n // Check file size\n if (stats.size > MAX_IMAGE_SIZE) {\n const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);\n return `Image file size (${sizeMB} MB) exceeds maximum allowed size of 4 MB`;\n }\n\n // Check file extension\n const ext = path.extname(cleanedPath).toLowerCase();\n if (!VALID_IMAGE_EXTENSIONS.includes(ext)) {\n return \"Image must be JPG or PNG format\";\n }\n\n return undefined;\n}\n\n// ==================== App ID Validation ====================\n\n/**\n * Validate and normalize app ID address\n * @param appID - App ID (must be a valid address)\n * @returns Normalized app address\n * @throws Error if app ID is not a valid address\n *\n * Note: Name resolution should be handled by CLI before calling SDK functions.\n * The SDK only accepts resolved addresses.\n */\nexport function validateAppID(appID: string | Address): Address {\n if (!appID) {\n throw new Error(\"App ID is required\");\n }\n\n // Normalize the input\n const normalized = typeof appID === \"string\" ? addHexPrefix(appID) : appID;\n\n // Check if it's a valid address\n if (isAddress(normalized)) {\n return normalized as Address;\n }\n\n throw new Error(`Invalid app ID: '${appID}' is not a valid address`);\n}\n\n// ==================== Log Visibility Validation ====================\n\nexport type LogVisibility = \"public\" | \"private\" | \"off\";\n\n/**\n * Validate and convert log visibility setting to internal format\n * @param logVisibility - Log visibility setting\n * @returns Object with logRedirect and publicLogs settings\n * @throws Error if log visibility value is invalid\n */\nexport function validateLogVisibility(logVisibility: LogVisibility): {\n logRedirect: string;\n publicLogs: boolean;\n} {\n switch (logVisibility) {\n case \"public\":\n return { logRedirect: \"always\", publicLogs: true };\n case \"private\":\n return { logRedirect: \"always\", publicLogs: false };\n case \"off\":\n return { logRedirect: \"\", publicLogs: false };\n default:\n throw new Error(\n `Invalid log-visibility value: ${logVisibility} (must be public, private, or off)`,\n );\n }\n}\n\n// ==================== Resource Usage Monitoring Validation ====================\n\nexport type ResourceUsageMonitoring = \"enable\" | \"disable\";\n\n/**\n * Validate and convert resource usage monitoring setting to internal format\n * @param resourceUsageMonitoring - Resource usage monitoring setting\n * @returns The resourceUsageAllow value for the Dockerfile label (\"always\" or \"never\")\n * @throws Error if resource usage monitoring value is invalid\n */\nexport function validateResourceUsageMonitoring(\n resourceUsageMonitoring: ResourceUsageMonitoring | undefined,\n): string {\n // Default to \"enable\" (always) if not specified\n if (!resourceUsageMonitoring) {\n return \"always\";\n }\n\n switch (resourceUsageMonitoring) {\n case \"enable\":\n return \"always\";\n case \"disable\":\n return \"never\";\n default:\n throw new Error(\n `Invalid resource-usage-monitoring value: ${resourceUsageMonitoring} (must be enable or disable)`,\n );\n }\n}\n\n// ==================== Sanitization Functions ====================\n\n/**\n * Check if URL has scheme\n */\nfunction hasScheme(rawURL: string): boolean {\n return rawURL.startsWith(\"http://\") || rawURL.startsWith(\"https://\");\n}\n\n/**\n * Sanitize string (HTML escape and trim)\n */\nexport function sanitizeString(s: string): string {\n return s\n .trim()\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n\n/**\n * Sanitize URL (add https:// if missing, validate)\n * @throws Error if URL is invalid after sanitization\n */\nexport function sanitizeURL(rawURL: string): string {\n rawURL = rawURL.trim();\n\n // Add https:// if no scheme is present\n if (!hasScheme(rawURL)) {\n rawURL = \"https://\" + rawURL;\n }\n\n // Validate\n const err = validateURL(rawURL);\n if (err) {\n throw new Error(err);\n }\n\n return rawURL;\n}\n\n/**\n * Sanitize X/Twitter URL (handle username-only input, normalize)\n * @throws Error if URL is invalid after sanitization\n */\nexport function sanitizeXURL(rawURL: string): string {\n rawURL = rawURL.trim();\n\n // Handle username-only input (e.g., \"@username\" or \"username\")\n if (!rawURL.includes(\"://\") && !rawURL.includes(\".\")) {\n // Remove @ if present\n const username = rawURL.startsWith(\"@\") ? rawURL.slice(1) : rawURL;\n rawURL = `https://x.com/${username}`;\n } else if (!hasScheme(rawURL)) {\n // Add https:// if URL-like but missing scheme\n rawURL = \"https://\" + rawURL;\n }\n\n // Normalize twitter.com to x.com\n rawURL = rawURL.replace(/twitter\\.com/g, \"x.com\");\n rawURL = rawURL.replace(/www\\.x\\.com/g, \"x.com\");\n\n // Validate\n const err = validateXURL(rawURL);\n if (err) {\n throw new Error(err);\n }\n\n return rawURL;\n}\n\n// ==================== Deploy/Upgrade Parameter Validation ====================\n\nexport interface DeployParams {\n dockerfilePath?: string;\n imageRef?: string;\n appName: string;\n envFilePath?: string;\n instanceType: string;\n logVisibility: LogVisibility;\n}\n\n/**\n * Validate deploy parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateDeployParams(params: Partial<DeployParams>): void {\n // Must have either dockerfilePath or imageRef\n if (!params.dockerfilePath && !params.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for deployment\");\n }\n\n // If imageRef is provided, validate it\n if (params.imageRef) {\n assertValidImageReference(params.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (params.dockerfilePath) {\n assertValidFilePath(params.dockerfilePath);\n }\n\n // App name is required\n if (!params.appName) {\n throw new Error(\"App name is required\");\n }\n validateAppName(params.appName);\n\n // Instance type is required\n if (!params.instanceType) {\n throw new Error(\"Instance type is required\");\n }\n\n // Log visibility is required\n if (!params.logVisibility) {\n throw new Error(\"Log visibility is required (public, private, or off)\");\n }\n validateLogVisibility(params.logVisibility);\n\n // Env file path is optional, but if provided, validate it exists\n if (params.envFilePath && params.envFilePath !== \"\") {\n const result = validateFilePath(params.envFilePath);\n if (result !== true) {\n throw new Error(`Invalid env file: ${result}`);\n }\n }\n}\n\nexport interface UpgradeParams {\n appID: string | Address;\n dockerfilePath?: string;\n imageRef?: string;\n envFilePath?: string;\n instanceType: string;\n logVisibility: LogVisibility;\n}\n\n/**\n * Validate upgrade parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateUpgradeParams(params: Partial<UpgradeParams>): void {\n // App ID is required\n if (!params.appID) {\n throw new Error(\"App ID is required for upgrade\");\n }\n // Validate app ID is a valid address (throws if not)\n validateAppID(params.appID);\n\n // Must have either dockerfilePath or imageRef\n if (!params.dockerfilePath && !params.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for upgrade\");\n }\n\n // If imageRef is provided, validate it\n if (params.imageRef) {\n assertValidImageReference(params.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (params.dockerfilePath) {\n assertValidFilePath(params.dockerfilePath);\n }\n\n // Instance type is required\n if (!params.instanceType) {\n throw new Error(\"Instance type is required\");\n }\n\n // Log visibility is required\n if (!params.logVisibility) {\n throw new Error(\"Log visibility is required (public, private, or off)\");\n }\n validateLogVisibility(params.logVisibility);\n\n // Env file path is optional, but if provided, validate it exists\n if (params.envFilePath && params.envFilePath !== \"\") {\n const result = validateFilePath(params.envFilePath);\n if (result !== true) {\n throw new Error(`Invalid env file: ${result}`);\n }\n }\n}\n\nexport interface CreateAppParams {\n name: string;\n language: string;\n template?: string;\n templateVersion?: string;\n}\n\n/**\n * Validate create app parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateCreateAppParams(params: Partial<CreateAppParams>): void {\n if (!params.name) {\n throw new Error(\"Project name is required\");\n }\n\n // Validate project name (no spaces)\n if (params.name.includes(\" \")) {\n throw new Error(\"Project name cannot contain spaces\");\n }\n\n if (!params.language) {\n throw new Error(\"Language is required\");\n }\n}\n\nexport interface LogsParams {\n appID: string | Address;\n watch?: boolean;\n}\n\n/**\n * Validate logs parameters\n * @throws Error if required parameters are missing or invalid\n */\nexport function validateLogsParams(params: Partial<LogsParams>): void {\n if (!params.appID) {\n throw new Error(\"App ID is required for viewing logs\");\n }\n // Validate app ID is a valid address (throws if not)\n validateAppID(params.appID);\n}\n","/**\n * Preflight checks\n */\n\nimport { Address, createPublicClient, http, PrivateKeyAccount } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\n\nimport { getEnvironmentConfig } from \"../config/environment\";\nimport { addHexPrefix, stripHexPrefix } from \"./helpers\";\n\nimport { Logger, EnvironmentConfig } from \"../types\";\n\nexport interface PreflightContext {\n privateKey: string;\n rpcUrl: string;\n environmentConfig: EnvironmentConfig;\n account: PrivateKeyAccount;\n selfAddress: Address;\n}\n\n/**\n * Do preflight checks - performs early validation of authentication and network connectivity\n */\nexport async function doPreflightChecks(\n options: Partial<{\n privateKey?: string;\n rpcUrl?: string;\n environment?: string;\n }>,\n logger: Logger,\n): Promise<PreflightContext> {\n // 1. Get and validate private key first (fail fast)\n logger.debug(\"Checking authentication...\");\n const privateKey = await getPrivateKeyOrFail(options.privateKey);\n\n // 2. Get environment configuration\n logger.debug(\"Determining environment...\");\n const environmentConfig = getEnvironmentConfig(options.environment || \"sepolia\");\n\n // 3. Get RPC URL (from option, env var, or environment default)\n let rpcUrl = options.rpcUrl;\n if (!rpcUrl) {\n rpcUrl = process.env.RPC_URL ?? environmentConfig.defaultRPCURL;\n }\n if (!rpcUrl) {\n throw new Error(\n `RPC URL is required. Provide via options.rpcUrl, RPC_URL env var, or ensure environment has default RPC URL`,\n );\n }\n\n // 4. Test network connectivity\n logger.debug(\"Testing network connectivity...\");\n const publicClient = createPublicClient({\n transport: http(rpcUrl),\n });\n\n try {\n // 5. Get chain ID\n const chainID = await publicClient.getChainId();\n if (BigInt(chainID) !== environmentConfig.chainID) {\n throw new Error(`Chain ID mismatch: expected ${environmentConfig.chainID}, got ${chainID}`);\n }\n } catch (err: any) {\n throw new Error(`Cannot connect to ${environmentConfig.name} RPC at ${rpcUrl}: ${err.message}`);\n }\n\n // 6. Create account from private key\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n const selfAddress = account.address;\n\n return {\n privateKey: privateKeyHex,\n rpcUrl,\n environmentConfig,\n account,\n selfAddress,\n };\n}\n\n/**\n * Get private key from options, environment variable, or keyring\n */\nasync function getPrivateKeyOrFail(privateKey?: string): Promise<string> {\n // Check option first\n if (privateKey) {\n validatePrivateKey(privateKey);\n return privateKey;\n }\n\n // Check environment variable\n if (process.env.PRIVATE_KEY) {\n validatePrivateKey(process.env.PRIVATE_KEY);\n return process.env.PRIVATE_KEY;\n }\n\n // TODO: Check keyring (OS keyring integration)\n // For now, throw error with instructions\n throw new Error(\n `private key required. Please provide it via:\n • Option: privateKey in deploy options\n • Environment: export PRIVATE_KEY=YOUR_KEY\n • Keyring: (not yet implemented)`,\n );\n}\n\n/**\n * Validate private key format\n */\nfunction validatePrivateKey(key: string): void {\n const cleaned = stripHexPrefix(key);\n if (!/^[0-9a-fA-F]{64}$/.test(cleaned)) {\n throw new Error(\"Invalid private key format (must be 64 hex characters)\");\n }\n}\n","/**\n * No-op telemetry client implementation\n */\n\nimport { TelemetryClient, Metric } from \"./types\";\n\n/**\n * NoopClient implements the TelemetryClient interface with no-op methods\n */\nexport class NoopClient implements TelemetryClient {\n /**\n * AddMetric implements the TelemetryClient interface\n */\n async addMetric(_metric: Metric): Promise<void> {\n // No-op\n }\n\n /**\n * Close implements the TelemetryClient interface\n */\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * Check if a client is a NoopClient\n */\nexport function isNoopClient(client: TelemetryClient): boolean {\n return client instanceof NoopClient;\n}\n","/**\n * PostHog telemetry client implementation\n *\n * Uses the official posthog-node library\n */\n\nimport { PostHog } from \"posthog-node\";\nimport { TelemetryClient, Metric, AppEnvironment } from \"./types\";\n\n/**\n * PostHogClient implements the TelemetryClient interface using posthog-node\n */\nexport class PostHogClient implements TelemetryClient {\n private readonly client: PostHog;\n private readonly namespace: string;\n private readonly appEnvironment: AppEnvironment;\n\n constructor(environment: AppEnvironment, namespace: string, apiKey: string, endpoint?: string) {\n this.namespace = namespace;\n this.appEnvironment = environment;\n\n // Initialize PostHog client\n // posthog-node expects the full URL for the host option\n const host = endpoint || \"https://us.i.posthog.com\";\n\n this.client = new PostHog(apiKey, {\n host: host,\n flushAt: 1, // Flush immediately for CLI/SDK usage\n flushInterval: 0, // Disable interval flushing\n });\n\n // Identify the user with their UUID\n this.client.identify({\n distinctId: environment.userUUID,\n properties: {\n os: environment.os,\n arch: environment.arch,\n ...(environment.cliVersion ? { cliVersion: environment.cliVersion } : {}),\n },\n });\n }\n\n /**\n * AddMetric implements the TelemetryClient interface\n */\n async addMetric(metric: Metric): Promise<void> {\n // Never throw errors from telemetry operations\n try {\n // Create properties map starting with base properties\n const props: Record<string, any> = {\n name: metric.name,\n value: metric.value,\n };\n\n // Add metric dimensions\n for (const [k, v] of Object.entries(metric.dimensions)) {\n props[k] = v;\n }\n\n // Capture event using the namespace as the event name\n // With flushAt: 1, events are automatically flushed after each capture\n this.client.capture({\n distinctId: this.appEnvironment.userUUID,\n event: this.namespace,\n properties: props,\n });\n } catch {\n // Silently ignore telemetry errors\n }\n }\n\n /**\n * Close implements the TelemetryClient interface\n */\n async close(): Promise<void> {\n try {\n // Shutdown PostHog client and flush any pending events\n // shutdown() is synchronous but internally handles async cleanup\n this.client.shutdown();\n } catch {\n // Silently ignore errors during shutdown\n }\n }\n}\n\n/**\n * Embedded PostHog API key (can be exposed in TypeScript)\n * This can be set at build time or overridden via environment variable\n */\n// @ts-ignore - POSTHOG_API_KEY_BUILD_TIME is injected at build time by tsup\ndeclare const POSTHOG_API_KEY_BUILD_TIME: string | undefined;\n\n/**\n * Get PostHog API key from environment variable or build-time constant\n */\nexport function getPostHogAPIKey(): string | undefined {\n // Priority order:\n // 1. Environment variable\n // 2. Build-time constant (set at build time)\n // Check environment variable first\n if (process.env.ECLOUD_POSTHOG_KEY) {\n return process.env.ECLOUD_POSTHOG_KEY;\n }\n\n // Return build-time constant if available\n // @ts-ignore - POSTHOG_API_KEY_BUILD_TIME is injected at build time\n return typeof POSTHOG_API_KEY_BUILD_TIME !== \"undefined\" ? POSTHOG_API_KEY_BUILD_TIME : undefined;\n}\n\n/**\n * Get PostHog endpoint from environment variable or default\n */\nexport function getPostHogEndpoint(): string {\n return process.env.ECLOUD_POSTHOG_ENDPOINT || \"https://us.i.posthog.com\";\n}\n","/**\n * Telemetry module for ECloud SDK and CLI\n *\n * Provides telemetry functionality matching the Go implementation.\n * Supports both \"ecloud-cli\" and \"ecloud-sdk\" namespaces.\n */\n\nimport { TelemetryClient, Metric, AppEnvironment } from \"./types\";\nimport { NoopClient, isNoopClient } from \"./noop\";\nimport { PostHogClient, getPostHogAPIKey, getPostHogEndpoint } from \"./posthog\";\nimport * as os from \"os\";\n\nexport * from \"./types\";\nexport * from \"./metricsContext\";\nexport * from \"./noop\";\nexport * from \"./posthog\";\nexport * from \"./wrapper\";\n\n/**\n * Options for creating a telemetry client\n */\nexport interface TelemetryClientOptions {\n /**\n * Whether telemetry is enabled (only enabled if explicitly set to true, defaults to disabled)\n */\n telemetryEnabled?: boolean;\n /**\n * PostHog API key (if not provided, will check environment variables)\n */\n apiKey?: string;\n /**\n * PostHog endpoint (if not provided, will use default)\n */\n endpoint?: string;\n}\n\n/**\n * Create a telemetry client\n *\n * @param environment - Application environment information (must include userUUID)\n * @param namespace - Namespace for telemetry events (\"ecloud-cli\" or \"ecloud-sdk\")\n * @param options - Optional telemetry client options\n * @returns TelemetryClient instance (NoopClient if telemetry is disabled or no API key)\n */\nexport function createTelemetryClient(\n environment: AppEnvironment,\n namespace: \"ecloud-cli\" | \"ecloud-sdk\",\n options?: TelemetryClientOptions,\n): TelemetryClient {\n // Check if telemetry is enabled\n // Only enabled if explicitly set to true\n // If undefined or false, telemetry is disabled\n const telemetryEnabled = options?.telemetryEnabled === true;\n\n // If telemetry is disabled, return noop client\n if (!telemetryEnabled) {\n return new NoopClient();\n }\n\n // Get API key from options, environment variable, or return noop\n const resolvedApiKey = options?.apiKey || getPostHogAPIKey();\n if (!resolvedApiKey) {\n // No API key available, return noop client\n return new NoopClient();\n }\n\n // Get endpoint from options or environment variable\n const endpoint = options?.endpoint || getPostHogEndpoint();\n\n try {\n return new PostHogClient(environment, namespace, resolvedApiKey, endpoint);\n } catch {\n // If initialization fails, return noop client\n return new NoopClient();\n }\n}\n\n/**\n * Create an AppEnvironment from current system information\n *\n * @param userUUID - User UUID for identification (required - no I/O in SDK)\n * @param cliVersion - Optional CLI version (for CLI usage)\n * @param osOverride - Optional OS override (defaults to current platform)\n * @param archOverride - Optional architecture override (defaults to current architecture)\n * @returns AppEnvironment with user UUID, OS, and architecture\n */\nexport function createAppEnvironment(\n userUUID: string,\n cliVersion?: string,\n osOverride?: string,\n archOverride?: string,\n): AppEnvironment {\n return {\n userUUID,\n cliVersion,\n os: osOverride || os.platform(),\n arch: archOverride || os.arch(),\n };\n}\n\n/**\n * Emit metrics from a metrics context\n *\n * @param client - Telemetry client to use\n * @param context - Metrics context containing metrics to emit\n * @returns Promise that resolves when all metrics are emitted\n */\nexport async function emitMetrics(\n client: TelemetryClient,\n context: {\n metrics: Metric[];\n properties: Record<string, string>;\n },\n): Promise<void> {\n if (isNoopClient(client)) {\n return;\n }\n\n // Emit each metric with properties merged into dimensions\n for (const metric of context.metrics) {\n const dimensions = {\n ...metric.dimensions,\n ...context.properties,\n };\n\n const metricWithProperties: Metric = {\n ...metric,\n dimensions,\n };\n\n try {\n await client.addMetric(metricWithProperties);\n } catch {\n // Silently ignore telemetry errors\n }\n }\n}\n","/**\n * MetricsContext management\n */\n\nimport { MetricsContext } from \"./types\";\n\n/**\n * Create a new metrics context\n */\nexport function createMetricsContext(): MetricsContext {\n return {\n startTime: new Date(),\n metrics: [],\n properties: {},\n };\n}\n\n/**\n * Add a metric to the context without dimensions\n */\nexport function addMetric(context: MetricsContext, name: string, value: number): void {\n addMetricWithDimensions(context, name, value, {});\n}\n\n/**\n * Add a metric to the context with dimensions\n */\nexport function addMetricWithDimensions(\n context: MetricsContext,\n name: string,\n value: number,\n dimensions: Record<string, string>,\n): void {\n context.metrics.push({\n name,\n value,\n dimensions,\n });\n}\n","/**\n * Telemetry wrapper utilities for SDK functions\n *\n * Provides helpers to wrap SDK function execution with telemetry tracking\n */\n\nimport {\n createTelemetryClient,\n createAppEnvironment,\n createMetricsContext,\n addMetric,\n addMetricWithDimensions,\n emitMetrics,\n} from \"./index\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Generate a random UUID for telemetry identification\n * Used when userUUID is not provided (SDK usage outside CLI)\n */\nfunction generateRandomUUID(): string {\n return randomUUID();\n}\n\n/**\n * Options for telemetry wrapper\n */\nexport interface TelemetryWrapperOptions {\n /**\n * Function name for telemetry (e.g., \"deploy\", \"upgrade\", \"createApp\")\n */\n functionName: string;\n /**\n * Skip telemetry if true (used when called from CLI)\n */\n skipTelemetry?: boolean;\n /**\n * Additional properties to include in telemetry\n */\n properties?: Record<string, string>;\n /**\n * User UUID for identification (required if skipTelemetry is false)\n * If not provided and telemetry is enabled, will generate a random UUID for this session\n */\n userUUID?: string;\n /**\n * Whether telemetry is enabled (defaults to true if not provided)\n */\n telemetryEnabled?: boolean;\n /**\n * PostHog API key (optional, will check environment variables if not provided)\n */\n apiKey?: string;\n /**\n * PostHog endpoint (optional, will use default if not provided)\n */\n endpoint?: string;\n}\n\n/**\n * Wrap a function execution with telemetry\n *\n * @param options - Telemetry wrapper options\n * @param action - The function to execute\n * @returns The result of the action\n */\nexport async function withSDKTelemetry<T>(\n options: TelemetryWrapperOptions,\n action: () => Promise<T>,\n): Promise<T> {\n // Skip telemetry if requested (e.g., when called from CLI)\n if (options.skipTelemetry) {\n return action();\n }\n\n // Generate a random UUID if not provided (for SDK usage outside CLI)\n // This ensures each SDK session has a unique identifier\n const userUUID = options.userUUID || generateRandomUUID();\n\n const environment = createAppEnvironment(userUUID);\n const client = createTelemetryClient(environment, \"ecloud-sdk\", {\n telemetryEnabled: options.telemetryEnabled,\n apiKey: options.apiKey,\n endpoint: options.endpoint,\n });\n const metrics = createMetricsContext();\n\n // Set source to identify SDK usage\n metrics.properties[\"source\"] = \"ecloud-sdk\";\n\n // Set function name in properties\n metrics.properties[\"function\"] = options.functionName;\n\n // Add any additional properties\n if (options.properties) {\n Object.assign(metrics.properties, options.properties);\n }\n\n // Add initial count metric\n addMetric(metrics, \"Count\", 1);\n\n let actionError: Error | undefined;\n let result: T;\n\n try {\n result = await action();\n return result;\n } catch (err) {\n actionError = err instanceof Error ? err : new Error(String(err));\n throw err;\n } finally {\n // Add result metric\n const resultValue = actionError ? \"Failure\" : \"Success\";\n const dimensions: Record<string, string> = {};\n if (actionError) {\n dimensions[\"error\"] = actionError.message;\n }\n addMetricWithDimensions(metrics, resultValue, 1, dimensions);\n\n // Add duration metric\n const duration = Date.now() - metrics.startTime.getTime();\n addMetric(metrics, \"DurationMilliseconds\", duration);\n\n // Emit all metrics\n try {\n await emitMetrics(client, metrics);\n await client.close();\n } catch {\n // Silently ignore telemetry errors\n }\n }\n}\n","/**\n * Main deploy function\n *\n * This is the main entry point for deploying applications to ecloud TEE.\n * It orchestrates all the steps: build, push, encrypt, and deploy on-chain.\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport type { WalletClient, PublicClient } from \"viem\";\nimport {\n DeployResult,\n Logger,\n AppId,\n PreparedDeploy,\n PreparedDeployData,\n EnvironmentConfig,\n} from \"../../../common/types\";\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport { ensureDockerIsRunning } from \"../../../common/docker/build\";\nimport { prepareRelease } from \"../../../common/release/prepare\";\nimport {\n deployApp,\n calculateAppID,\n getMaxActiveAppsPerUser,\n getActiveAppCount,\n prepareDeployBatch,\n executeDeployBatch,\n} from \"../../../common/contract/caller\";\nimport { estimateBatchGas } from \"../../../common/contract/eip7702\";\nimport { type GasEstimate } from \"../../../common/contract/caller\";\nimport { watchUntilRunning } from \"../../../common/contract/watcher\";\nimport {\n validateAppName,\n validateLogVisibility,\n validateResourceUsageMonitoring,\n assertValidImageReference,\n assertValidFilePath,\n LogVisibility,\n ResourceUsageMonitoring,\n} from \"../../../common/utils/validation\";\nimport { doPreflightChecks, PreflightContext } from \"../../../common/utils/preflight\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\n/**\n * Required deploy options for SDK (non-interactive)\n */\nexport interface SDKDeployOptions {\n /** Private key for signing transactions (hex string with or without 0x prefix) */\n privateKey: string;\n /** RPC URL for blockchain connection - optional, uses environment default if not provided */\n rpcUrl?: string;\n /** Environment name (e.g., 'sepolia', 'mainnet-alpha') - defaults to 'sepolia' */\n environment?: string;\n /** Path to Dockerfile (if building from Dockerfile) - either this or imageRef is required */\n dockerfilePath?: string;\n /** Image reference (registry/path:tag) - either this or dockerfilePath is required */\n imageRef?: string;\n /** Path to .env file - optional */\n envFilePath?: string;\n /** App name - required */\n appName: string;\n /** Instance type SKU - required */\n instanceType: string;\n /** Log visibility setting - required */\n logVisibility: LogVisibility;\n /** Resource usage monitoring setting - optional, defaults to 'enable' */\n resourceUsageMonitoring?: ResourceUsageMonitoring;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n /** Skip telemetry (used when called from CLI) - optional */\n skipTelemetry?: boolean;\n}\n\n/**\n * Result from prepareDeploy - includes prepared batch and gas estimate\n */\nexport interface PrepareDeployResult {\n /** Prepared deployment state */\n prepared: PreparedDeploy;\n /** Gas estimate for the batch transaction */\n gasEstimate: GasEstimate;\n}\n\n/** Options for executing a prepared deployment */\nexport interface ExecuteDeployOptions {\n prepared: PreparedDeploy;\n context: {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n };\n gas?: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint };\n logger?: Logger;\n skipTelemetry?: boolean;\n}\n\n/**\n * Validate deploy options and throw descriptive errors for missing/invalid params\n */\nfunction validateDeployOptions(options: SDKDeployOptions): void {\n // Private key is required\n if (!options.privateKey) {\n throw new Error(\"privateKey is required for deployment\");\n }\n\n // Must have either dockerfilePath or imageRef\n if (!options.dockerfilePath && !options.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for deployment\");\n }\n\n // If imageRef is provided, validate it\n if (options.imageRef) {\n assertValidImageReference(options.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (options.dockerfilePath) {\n assertValidFilePath(options.dockerfilePath);\n }\n\n // App name is required\n if (!options.appName) {\n throw new Error(\"appName is required for deployment\");\n }\n validateAppName(options.appName);\n\n // Instance type is required\n if (!options.instanceType) {\n throw new Error(\"instanceType is required for deployment\");\n }\n\n // Log visibility is required\n if (!options.logVisibility) {\n throw new Error(\"logVisibility is required (must be 'public', 'private', or 'off')\");\n }\n // Validate log visibility value\n validateLogVisibility(options.logVisibility);\n}\n\n/**\n * Deploy an application to ECloud TEE\n *\n * This function is non-interactive and requires all parameters to be provided explicitly.\n *\n * Flow:\n * 1. Validate all required parameters\n * 2. Preflight checks (auth, network, etc.)\n * 3. Check quota availability\n * 4. Ensure Docker is running\n * 5. Generate random salt and calculate app ID\n * 6. Prepare the release (includes build/push if needed)\n * 7. Deploy the app on-chain\n * 8. Watch until app is running\n *\n * @param options - Required deployment options\n * @param logger - Optional logger instance\n * @returns DeployResult with appID, txHash, appName, imageRef, and ipAddress\n * @throws Error if required parameters are missing or invalid\n */\nexport async function deploy(\n options: SDKDeployOptions,\n logger: Logger = defaultLogger,\n): Promise<DeployResult> {\n return withSDKTelemetry(\n {\n functionName: \"deploy\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Validate all required parameters upfront\n validateDeployOptions(options);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 2. Do preflight checks (auth, network, etc.)\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 3. Check quota availability\n logger.debug(\"Checking quota availability...\");\n await checkQuotaAvailable(preflightCtx);\n\n // 4. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const appName = options.appName;\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 5. Generate random salt\n const salt = generateRandomSalt();\n logger.debug(`Generated salt: ${Buffer.from(salt).toString(\"hex\")}`);\n\n // 6. Get app ID (calculate from salt and address)\n logger.debug(\"Calculating app ID...\");\n const appIDToBeDeployed = await calculateAppID(\n preflightCtx.privateKey,\n options.rpcUrl || preflightCtx.rpcUrl,\n preflightCtx.environmentConfig,\n salt,\n );\n logger.info(``);\n logger.info(`App ID: ${appIDToBeDeployed}`);\n logger.info(``);\n\n // 7. Prepare the release (includes build/push if needed, with automatic retry on permission errors)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appIDToBeDeployed,\n },\n logger,\n );\n\n // 8. Deploy the app\n logger.info(\"Deploying on-chain...\");\n const deployResult = await deployApp(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n salt,\n release,\n publicLogs,\n imageRef: finalImageRef,\n gas: options.gas,\n },\n logger,\n );\n\n // 9. Watch until app is running\n logger.info(\"Waiting for app to start...\");\n const ipAddress = await watchUntilRunning(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: deployResult.appId,\n },\n logger,\n );\n\n return {\n appId: deployResult.appId,\n txHash: deployResult.txHash,\n appName,\n imageRef: finalImageRef,\n ipAddress,\n };\n },\n );\n}\n\n/**\n * Check quota availability - verifies that the user has deployment quota available\n * by checking their allowlist status on the contract\n */\nasync function checkQuotaAvailable(preflightCtx: PreflightContext): Promise<void> {\n const rpcUrl = preflightCtx.rpcUrl;\n const environmentConfig = preflightCtx.environmentConfig;\n const userAddress = preflightCtx.selfAddress;\n\n // Check user's quota limit from contract\n let maxQuota: number;\n try {\n maxQuota = await getMaxActiveAppsPerUser(rpcUrl, environmentConfig, userAddress);\n } catch (err: any) {\n throw new Error(`failed to get quota limit: ${err.message}`);\n }\n\n // If quota is 0, user needs to subscribe\n if (maxQuota === 0) {\n throw new Error(\n \"no app quota available. Run 'ecloud billing subscribe' to enable app deployment\",\n );\n }\n\n // Check current active app count from contract\n let activeCount: number;\n try {\n activeCount = await getActiveAppCount(rpcUrl, environmentConfig, userAddress);\n } catch (err: any) {\n throw new Error(`failed to get active app count: ${err.message}`);\n }\n\n // Check if quota is reached\n if (activeCount >= maxQuota) {\n throw new Error(\n `app quota reached for ${environmentConfig.name} (${activeCount}/${maxQuota}). Please contact the Eigen team at eigencloud_support@eigenlabs.org for additional capacity`,\n );\n }\n}\n\n/**\n * Generate random 32-byte salt\n */\nfunction generateRandomSalt(): Uint8Array {\n const salt = new Uint8Array(32);\n crypto.getRandomValues(salt);\n return salt;\n}\n\n/**\n * Prepare deployment - does all work up to the transaction\n *\n * This allows CLI to:\n * 1. Call prepareDeploy to build image, prepare release, get gas estimate\n * 2. Prompt user to confirm the cost\n * 3. Call executeDeploy with confirmed gas params\n */\nexport async function prepareDeploy(\n options: Omit<SDKDeployOptions, \"gas\"> & { skipTelemetry?: boolean },\n logger: Logger = defaultLogger,\n): Promise<PrepareDeployResult> {\n return withSDKTelemetry(\n {\n functionName: \"prepareDeploy\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Validate all required parameters upfront\n validateDeployOptions(options as SDKDeployOptions);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 2. Do preflight checks (auth, network, etc.)\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 3. Check quota availability\n logger.debug(\"Checking quota availability...\");\n await checkQuotaAvailable(preflightCtx);\n\n // 4. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const appName = options.appName;\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 5. Generate random salt\n const salt = generateRandomSalt();\n logger.debug(`Generated salt: ${Buffer.from(salt).toString(\"hex\")}`);\n\n // 6. Get app ID (calculate from salt and address)\n logger.debug(\"Calculating app ID...\");\n const appIDToBeDeployed = await calculateAppID(\n preflightCtx.privateKey,\n options.rpcUrl || preflightCtx.rpcUrl,\n preflightCtx.environmentConfig,\n salt,\n );\n logger.info(``);\n logger.info(`App ID: ${appIDToBeDeployed}`);\n logger.info(``);\n\n // 7. Prepare the release (includes build/push if needed)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appIDToBeDeployed,\n },\n logger,\n );\n\n // 8. Prepare the deploy batch (creates executions without sending)\n logger.debug(\"Preparing deploy batch...\");\n const batch = await prepareDeployBatch(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n salt,\n release,\n publicLogs,\n },\n logger,\n );\n\n // 9. Estimate gas for the batch\n logger.debug(\"Estimating gas...\");\n const gasEstimate = await estimateBatchGas({\n publicClient: batch.publicClient,\n environmentConfig: batch.environmentConfig,\n executions: batch.executions,\n });\n\n // Extract only data fields for public type (clients stay internal)\n const data: PreparedDeployData = {\n appId: batch.appId,\n salt: batch.salt,\n executions: batch.executions,\n };\n\n return {\n prepared: {\n data,\n appName,\n imageRef: finalImageRef,\n },\n gasEstimate,\n };\n },\n );\n}\n\n/**\n * Execute a prepared deployment\n *\n * Call this after prepareDeploy and user confirmation.\n * Note: This only submits the on-chain transaction. Call watchDeployment separately\n * to wait for the app to be running.\n */\nexport async function executeDeploy(options: ExecuteDeployOptions): Promise<DeployResult> {\n const { prepared, context, gas, logger = defaultLogger, skipTelemetry } = options;\n\n return withSDKTelemetry(\n {\n functionName: \"executeDeploy\",\n skipTelemetry: skipTelemetry,\n },\n async () => {\n // Execute the batch transaction\n logger.info(\"Deploying on-chain...\");\n const { appId, txHash } = await executeDeployBatch(prepared.data, context, gas, logger);\n\n return {\n appId,\n txHash,\n appName: prepared.appName,\n imageRef: prepared.imageRef,\n };\n },\n );\n}\n\n/**\n * Watch a deployment until the app is running\n *\n * Call this after executeDeploy to wait for the app to be provisioned.\n * Can be called separately to allow for intermediate operations (e.g., profile upload).\n */\nexport async function watchDeployment(\n appId: string,\n privateKey: string,\n rpcUrl: string,\n environment: string,\n logger: Logger = defaultLogger,\n clientId?: string,\n skipTelemetry?: boolean,\n): Promise<string | undefined> {\n return withSDKTelemetry(\n {\n functionName: \"watchDeployment\",\n skipTelemetry: skipTelemetry,\n properties: {\n environment,\n },\n },\n async () => {\n const environmentConfig = getEnvironmentConfig(environment);\n\n logger.info(\"Waiting for app to start...\");\n return watchUntilRunning(\n {\n privateKey,\n rpcUrl,\n environmentConfig,\n appId: appId as AppId,\n clientId,\n },\n logger,\n );\n },\n );\n}\n\n// Re-export for convenience\nexport { extractAppNameFromImage } from \"../../../common/utils/validation\";\n","/**\n * Permission checking utilities\n */\n\nimport { Address, createPublicClient, http, Hex } from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\nimport PermissionControllerABI from \"../abis/PermissionController.json\";\nimport { getChainFromID } from \"./helpers\";\n\n// Permission constants (matching Go version)\nconst AnyoneCanCallAddress = \"0x493219d9949348178af1f58740655951a8cd110c\" as Address;\nconst ApiPermissionsTarget = \"0x57ee1fb74c1087e26446abc4fb87fd8f07c43d8d\" as Address;\nconst CanViewAppLogsPermission = \"0x2fd3f2fe\" as Hex;\n\n/**\n * Check if an app currently has public log viewing permissions\n */\nexport async function checkAppLogPermission(\n preflightCtx: {\n environmentConfig: EnvironmentConfig;\n rpcUrl: string;\n },\n appAddress: Address,\n logger: Logger,\n): Promise<boolean> {\n const chain = getChainFromID(preflightCtx.environmentConfig.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(preflightCtx.rpcUrl),\n });\n\n try {\n // Call the canCall method on PermissionController\n const canCall = await publicClient.readContract({\n address: preflightCtx.environmentConfig.permissionControllerAddress as Address,\n abi: PermissionControllerABI,\n functionName: \"canCall\",\n args: [appAddress, AnyoneCanCallAddress, ApiPermissionsTarget, CanViewAppLogsPermission],\n });\n\n return canCall as boolean;\n } catch (err: any) {\n logger.warn(`Failed to check log permission: ${err.message}. Assuming private logs.`);\n // Default to false (private) on error\n return false;\n }\n}\n","/**\n * Main upgrade function\n *\n * This is the main entry point for upgrading existing applications on ecloud TEE.\n * It orchestrates all the steps: build, push, encrypt, and upgrade on-chain.\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport { Address, Hex } from \"viem\";\nimport type { WalletClient, PublicClient } from \"viem\";\nimport {\n Logger,\n AppId,\n PreparedUpgrade,\n PreparedUpgradeData,\n EnvironmentConfig,\n} from \"../../../common/types\";\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport { ensureDockerIsRunning } from \"../../../common/docker/build\";\nimport { prepareRelease } from \"../../../common/release/prepare\";\nimport {\n upgradeApp,\n prepareUpgradeBatch,\n executeUpgradeBatch,\n type GasEstimate,\n} from \"../../../common/contract/caller\";\nimport { estimateBatchGas } from \"../../../common/contract/eip7702\";\nimport { watchUntilUpgradeComplete } from \"../../../common/contract/watcher\";\nimport {\n validateAppID,\n validateLogVisibility,\n validateResourceUsageMonitoring,\n assertValidImageReference,\n assertValidFilePath,\n LogVisibility,\n ResourceUsageMonitoring,\n} from \"../../../common/utils/validation\";\nimport { doPreflightChecks } from \"../../../common/utils/preflight\";\nimport { checkAppLogPermission } from \"../../../common/utils/permissions\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\n/**\n * Required upgrade options for SDK (non-interactive)\n */\nexport interface SDKUpgradeOptions {\n /** App ID to upgrade - required */\n appId: string | Address;\n /** Private key for signing transactions (hex string with or without 0x prefix) */\n privateKey: string;\n /** RPC URL for blockchain connection - optional, uses environment default if not provided */\n rpcUrl?: string;\n /** Environment name (e.g., 'sepolia', 'mainnet-alpha') - defaults to 'sepolia' */\n environment?: string;\n /** Path to Dockerfile (if building from Dockerfile) - either this or imageRef is required */\n dockerfilePath?: string;\n /** Image reference (registry/path:tag) - either this or dockerfilePath is required */\n imageRef?: string;\n /** Path to .env file - optional */\n envFilePath?: string;\n /** Instance type SKU - required */\n instanceType: string;\n /** Log visibility setting - required */\n logVisibility: LogVisibility;\n /** Resource usage monitoring setting - optional, defaults to 'enable' */\n resourceUsageMonitoring?: ResourceUsageMonitoring;\n /** Optional gas params from estimation */\n gas?: {\n maxFeePerGas?: bigint;\n maxPriorityFeePerGas?: bigint;\n };\n /** Skip telemetry (used when called from CLI) - optional */\n skipTelemetry?: boolean;\n}\n\nexport interface UpgradeResult {\n /** App ID (contract address) */\n appId: AppId;\n /** Final image reference */\n imageRef: string;\n /** Transaction hash */\n txHash: Hex;\n}\n\n/**\n * Result from prepareUpgrade - includes prepared batch and gas estimate\n */\nexport interface PrepareUpgradeResult {\n /** Prepared upgrade state */\n prepared: PreparedUpgrade;\n /** Gas estimate for the batch transaction */\n gasEstimate: GasEstimate;\n}\n\n/** Options for executing a prepared upgrade */\nexport interface ExecuteUpgradeOptions {\n prepared: PreparedUpgrade;\n context: {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n };\n gas?: { maxFeePerGas?: bigint; maxPriorityFeePerGas?: bigint };\n logger?: Logger;\n skipTelemetry?: boolean;\n}\n\n/**\n * Validate upgrade options and throw descriptive errors for missing/invalid params\n */\nfunction validateUpgradeOptions(options: SDKUpgradeOptions): Address {\n // Private key is required\n if (!options.privateKey) {\n throw new Error(\"privateKey is required for upgrade\");\n }\n\n // App ID is required\n if (!options.appId) {\n throw new Error(\"appId is required for upgrade\");\n }\n // Validate app ID (must be a valid address - name resolution is done by CLI)\n const resolvedAppID = validateAppID(options.appId);\n\n // Must have either dockerfilePath or imageRef\n if (!options.dockerfilePath && !options.imageRef) {\n throw new Error(\"Either dockerfilePath or imageRef is required for upgrade\");\n }\n\n // If imageRef is provided, validate it\n if (options.imageRef) {\n assertValidImageReference(options.imageRef);\n }\n\n // If dockerfilePath is provided, validate it exists\n if (options.dockerfilePath) {\n assertValidFilePath(options.dockerfilePath);\n }\n\n // Instance type is required\n if (!options.instanceType) {\n throw new Error(\"instanceType is required for upgrade\");\n }\n\n // Log visibility is required\n if (!options.logVisibility) {\n throw new Error(\"logVisibility is required (must be 'public', 'private', or 'off')\");\n }\n // Validate log visibility value\n validateLogVisibility(options.logVisibility);\n\n return resolvedAppID;\n}\n\n/**\n * Upgrade an existing application on ECloud TEE\n *\n * This function is non-interactive and requires all parameters to be provided explicitly.\n *\n * Flow:\n * 1. Validate all required parameters\n * 2. Preflight checks (auth, network, etc.)\n * 3. Ensure Docker is running\n * 4. Prepare the release (includes build/push if needed)\n * 5. Check current permission state and determine if change is needed\n * 6. Upgrade the app on-chain\n * 7. Watch until upgrade completes\n *\n * @param options - Required upgrade options\n * @param logger - Optional logger instance\n * @returns UpgradeResult with appID, imageRef, and txHash\n * @throws Error if required parameters are missing or invalid\n */\nexport async function upgrade(\n options: SDKUpgradeOptions,\n logger: Logger = defaultLogger,\n): Promise<UpgradeResult> {\n return withSDKTelemetry(\n {\n functionName: \"upgrade\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Do preflight checks (auth, network, etc.) first\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 2. Validate all required parameters upfront\n const appID = validateUpgradeOptions(options);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 3. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 4. Prepare the release (includes build/push if needed, with automatic retry on permission errors)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n },\n logger,\n );\n\n // 5. Check current permission state and determine if change is needed\n logger.debug(\"Checking current log permission state...\");\n const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);\n const needsPermissionChange = currentlyPublic !== publicLogs;\n\n // 6. Upgrade the app\n logger.info(\"Upgrading on-chain...\");\n const txHash = await upgradeApp(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n release,\n publicLogs,\n needsPermissionChange,\n imageRef: finalImageRef,\n gas: options.gas,\n },\n logger,\n );\n\n // 7. Watch until upgrade completes\n logger.info(\"Waiting for upgrade to complete...\");\n await watchUntilUpgradeComplete(\n {\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n },\n logger,\n );\n\n return {\n appId: appID,\n imageRef: finalImageRef,\n txHash,\n };\n },\n );\n}\n\n/**\n * Prepare upgrade - does all work up to the transaction\n *\n * This allows CLI to:\n * 1. Call prepareUpgrade to build image, prepare release, get gas estimate\n * 2. Prompt user to confirm the cost\n * 3. Call executeUpgrade with confirmed gas params\n */\nexport async function prepareUpgrade(\n options: Omit<SDKUpgradeOptions, \"gas\"> & { skipTelemetry?: boolean },\n logger: Logger = defaultLogger,\n): Promise<PrepareUpgradeResult> {\n return withSDKTelemetry(\n {\n functionName: \"prepareUpgrade\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n environment: options.environment || \"sepolia\",\n },\n },\n async () => {\n // 1. Do preflight checks (auth, network, etc.) first\n logger.debug(\"Performing preflight checks...\");\n const preflightCtx = await doPreflightChecks(\n {\n privateKey: options.privateKey,\n rpcUrl: options.rpcUrl,\n environment: options.environment,\n },\n logger,\n );\n\n // 2. Validate all required parameters upfront\n const appID = validateUpgradeOptions(options as SDKUpgradeOptions);\n\n // Convert log visibility to internal format\n const { logRedirect, publicLogs } = validateLogVisibility(options.logVisibility);\n\n // Convert resource usage monitoring to internal format (defaults to \"always\")\n const resourceUsageAllow = validateResourceUsageMonitoring(options.resourceUsageMonitoring);\n\n // 3. Check if docker is running, else try to start it\n logger.debug(\"Checking Docker...\");\n await ensureDockerIsRunning();\n\n // Use provided values (already validated)\n const dockerfilePath = options.dockerfilePath || \"\";\n const imageRef = options.imageRef || \"\";\n const envFilePath = options.envFilePath || \"\";\n const instanceType = options.instanceType;\n\n // 4. Prepare the release (includes build/push if needed)\n logger.info(\"Preparing release...\");\n const { release, finalImageRef } = await prepareRelease(\n {\n dockerfilePath,\n imageRef,\n envFilePath,\n logRedirect,\n resourceUsageAllow,\n instanceType,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n },\n logger,\n );\n\n // 5. Check current permission state and determine if change is needed\n logger.debug(\"Checking current log permission state...\");\n const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);\n const needsPermissionChange = currentlyPublic !== publicLogs;\n\n // 6. Prepare the upgrade batch (creates executions without sending)\n logger.debug(\"Preparing upgrade batch...\");\n const batch = await prepareUpgradeBatch({\n privateKey: preflightCtx.privateKey,\n rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,\n environmentConfig: preflightCtx.environmentConfig,\n appId: appID,\n release,\n publicLogs,\n needsPermissionChange,\n });\n\n // 7. Estimate gas for the batch\n logger.debug(\"Estimating gas...\");\n const gasEstimate = await estimateBatchGas({\n publicClient: batch.publicClient,\n environmentConfig: batch.environmentConfig,\n executions: batch.executions,\n });\n\n // Extract only data fields for public type (clients stay internal)\n const data: PreparedUpgradeData = {\n appId: batch.appId,\n executions: batch.executions,\n };\n\n return {\n prepared: {\n data,\n appId: appID,\n imageRef: finalImageRef,\n },\n gasEstimate,\n };\n },\n );\n}\n\n/**\n * Execute a prepared upgrade\n *\n * Call this after prepareUpgrade and user confirmation.\n * Note: This only submits the on-chain transaction. Call watchUpgrade separately\n * to wait for the upgrade to complete.\n */\nexport async function executeUpgrade(options: ExecuteUpgradeOptions): Promise<UpgradeResult> {\n const { prepared, context, gas, logger = defaultLogger, skipTelemetry } = options;\n\n return withSDKTelemetry(\n {\n functionName: \"executeUpgrade\",\n skipTelemetry: skipTelemetry,\n },\n async () => {\n // Execute the batch transaction\n logger.info(\"Upgrading on-chain...\");\n const txHash = await executeUpgradeBatch(prepared.data, context, gas, logger);\n\n return {\n appId: prepared.appId,\n imageRef: prepared.imageRef,\n txHash,\n };\n },\n );\n}\n\n/**\n * Watch an upgrade until it completes\n *\n * Call this after executeUpgrade to wait for the upgrade to finish.\n * Can be called separately to allow for intermediate operations.\n */\nexport async function watchUpgrade(\n appId: string,\n privateKey: string,\n rpcUrl: string,\n environment: string,\n logger: Logger = defaultLogger,\n clientId?: string,\n skipTelemetry?: boolean,\n): Promise<void> {\n return withSDKTelemetry(\n {\n functionName: \"watchUpgrade\",\n skipTelemetry: skipTelemetry,\n properties: {\n environment,\n },\n },\n async () => {\n const environmentConfig = getEnvironmentConfig(environment);\n\n logger.info(\"Waiting for upgrade to complete...\");\n await watchUntilUpgradeComplete(\n {\n privateKey,\n rpcUrl,\n environmentConfig,\n appId: appId as Address,\n clientId,\n },\n logger,\n );\n },\n );\n}\n","/**\n * Create command\n *\n * Creates a new app project from a template\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Logger } from \"../../../common/types\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport {\n fetchTemplateCatalog,\n getTemplate,\n getCategoryDescriptions,\n DEFAULT_TEMPLATE_REPO,\n DEFAULT_TEMPLATE_VERSION,\n ENV_VAR_USE_LOCAL_TEMPLATES,\n ENV_VAR_TEMPLATES_PATH,\n type TemplateEntry,\n} from \"../../../common/templates/catalog\";\nimport { fetchTemplate, fetchTemplateSubdirectory } from \"../../../common/templates/git\";\nimport { postProcessTemplate } from \"../../../common/templates/postprocess\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\n\n/**\n * Required create app options for SDK (non-interactive)\n */\nexport interface SDKCreateAppOpts {\n /** Project name - required */\n name: string;\n /** Programming language - required (typescript, golang, rust, python) */\n language: string;\n /** Template name/category (e.g., \"minimal\") or custom template URL - optional, defaults to first available */\n template?: string;\n /** Template version/ref - optional */\n templateVersion?: string;\n /** Verbose output - optional */\n verbose?: boolean;\n /** Skip telemetry (used when called from CLI) - optional */\n skipTelemetry?: boolean;\n}\n\n/**\n * Legacy interface for backward compatibility\n * @deprecated Use SDKCreateAppOpts instead\n */\nexport interface CreateAppOpts {\n name?: string;\n language?: string;\n template?: string;\n templateVersion?: string;\n verbose?: boolean;\n skipTelemetry?: boolean;\n}\n\n// Language configuration\nexport const PRIMARY_LANGUAGES = [\"typescript\", \"golang\", \"rust\", \"python\"];\n\nexport const LANGUAGE_FILES: Record<string, string[]> = {\n typescript: [\"package.json\"],\n rust: [\"Cargo.toml\", \"Dockerfile\"],\n golang: [\"go.mod\"],\n};\n\n/**\n * Project configuration\n */\ninterface ProjectConfig {\n name: string;\n language?: string;\n templateName?: string;\n templateEntry?: TemplateEntry;\n repoURL: string;\n ref: string;\n subPath: string;\n}\n\n/**\n * Validate project name\n */\nfunction validateProjectName(name: string): void {\n if (!name) {\n throw new Error(\"Project name is required\");\n }\n if (name.includes(\" \")) {\n throw new Error(\"Project name cannot contain spaces\");\n }\n}\n\n/**\n * Validate language\n */\nfunction validateLanguage(language: string): void {\n if (!language) {\n throw new Error(\"Language is required\");\n }\n\n if (!PRIMARY_LANGUAGES.includes(language)) {\n throw new Error(\n `Invalid language: ${language}. Must be one of: ${PRIMARY_LANGUAGES.join(\", \")}`,\n );\n }\n}\n\n/**\n * Check if a string is a URL\n */\nfunction isURL(str: string): boolean {\n try {\n new URL(str);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Get available template categories for a language\n */\nexport async function getAvailableTemplates(\n language: string,\n): Promise<Array<{ name: string; description: string }>> {\n const catalog = await fetchTemplateCatalog();\n const categoryDescriptions = getCategoryDescriptions(catalog, language);\n\n if (Object.keys(categoryDescriptions).length === 0) {\n throw new Error(`No templates found for language ${language}`);\n }\n\n // Sort categories alphabetically for consistent ordering\n const categories = Object.keys(categoryDescriptions).sort();\n\n return categories.map((category) => ({\n name: category,\n description: categoryDescriptions[category] || \"\",\n }));\n}\n\n/**\n * Create a new app project from template\n *\n * This function is non-interactive and requires all parameters to be provided explicitly.\n *\n * @param options - Required options including name and language\n * @param logger - Optional logger instance\n * @throws Error if required parameters are missing or invalid\n */\nexport async function createApp(\n options: SDKCreateAppOpts | CreateAppOpts,\n logger: Logger = defaultLogger,\n): Promise<void> {\n return withSDKTelemetry(\n {\n functionName: \"createApp\",\n skipTelemetry: options.skipTelemetry,\n properties: {\n language: options.language || \"\",\n },\n },\n async () => {\n // 1. Validate required parameters\n validateProjectName(options.name || \"\");\n validateLanguage(options.language || \"\");\n\n // 2. Gather project configuration\n const cfg = await gatherProjectConfig(\n {\n ...options,\n name: options.name!,\n language: options.language!,\n },\n logger,\n );\n\n // 3. Check if directory exists\n if (fs.existsSync(cfg.name)) {\n throw new Error(`Directory ${cfg.name} already exists`);\n }\n\n // 4. Create project directory\n fs.mkdirSync(cfg.name, { mode: 0o755 });\n\n try {\n // 5. Populate project from template\n await populateProjectFromTemplate(cfg, options, logger);\n\n // 6. Post-process template\n if (cfg.subPath && cfg.language && cfg.templateEntry) {\n await postProcessTemplate(cfg.name, cfg.language, cfg.templateEntry, logger);\n }\n\n logger.info(`Successfully created ${cfg.language || \"project\"} project: ${cfg.name}`);\n } catch (error: any) {\n // Cleanup on failure\n fs.rmSync(cfg.name, { recursive: true, force: true });\n throw error;\n }\n },\n );\n}\n\n/**\n * Gather project configuration (non-interactive)\n */\nasync function gatherProjectConfig(\n options: { name: string; language: string; template?: string; templateVersion?: string },\n logger: Logger,\n): Promise<ProjectConfig> {\n const cfg: ProjectConfig = {\n repoURL: DEFAULT_TEMPLATE_REPO,\n ref: DEFAULT_TEMPLATE_VERSION,\n subPath: \"\",\n name: options.name,\n };\n\n // Handle custom template repo (if template is a URL)\n const customTemplateRepo = options.template;\n if (customTemplateRepo && isURL(customTemplateRepo)) {\n cfg.repoURL = customTemplateRepo;\n cfg.ref = options.templateVersion || DEFAULT_TEMPLATE_VERSION;\n return cfg;\n }\n\n // Handle built-in templates\n cfg.language = options.language;\n\n // Get template name (category)\n let templateName = customTemplateRepo; // If provided and not a URL, it's a template name\n\n if (!templateName) {\n // Default to first available template for the language\n const availableTemplates = await getAvailableTemplates(options.language);\n if (availableTemplates.length === 0) {\n throw new Error(`No templates found for language ${options.language}`);\n }\n templateName = availableTemplates[0].name;\n logger.debug(`Using default template: ${templateName}`);\n }\n cfg.templateName = templateName;\n\n // Resolve template details from catalog\n const catalog = await fetchTemplateCatalog();\n const matchedTemplate = getTemplate(catalog, templateName, options.language);\n cfg.templateEntry = matchedTemplate;\n cfg.repoURL = DEFAULT_TEMPLATE_REPO;\n cfg.ref = options.templateVersion || DEFAULT_TEMPLATE_VERSION;\n cfg.subPath = matchedTemplate.path;\n\n return cfg;\n}\n\n/**\n * Populate project from template\n */\nasync function populateProjectFromTemplate(\n cfg: ProjectConfig,\n options: { verbose?: boolean },\n logger: Logger,\n): Promise<void> {\n // Handle local templates for development\n if (process.env[ENV_VAR_USE_LOCAL_TEMPLATES] === \"true\") {\n let eigenxTemplatesPath = process.env[ENV_VAR_TEMPLATES_PATH];\n if (!eigenxTemplatesPath) {\n // Look for eigenx-templates as a sibling directory\n const possiblePaths = [\"eigenx-templates\", \"../eigenx-templates\"];\n for (const possiblePath of possiblePaths) {\n const testPath = path.join(possiblePath, \"templates\");\n if (fs.existsSync(testPath)) {\n eigenxTemplatesPath = possiblePath;\n break;\n }\n }\n if (!eigenxTemplatesPath) {\n throw new Error(\n `Cannot find eigenx-templates directory. Set ${ENV_VAR_TEMPLATES_PATH} or ensure eigenx-templates is a sibling directory`,\n );\n }\n }\n\n const localTemplatePath = path.join(eigenxTemplatesPath, cfg.subPath);\n if (!fs.existsSync(localTemplatePath)) {\n throw new Error(`Local template not found at ${localTemplatePath}`);\n }\n\n await copyDirectory(localTemplatePath, cfg.name);\n logger.info(`Using local template from ${localTemplatePath}`);\n return;\n }\n\n // Fetch from remote repository\n if (cfg.subPath) {\n await fetchTemplateSubdirectory(cfg.repoURL, cfg.ref, cfg.subPath, cfg.name, logger);\n } else {\n await fetchTemplate(\n cfg.repoURL,\n cfg.ref,\n cfg.name,\n { verbose: options.verbose || false },\n logger,\n );\n }\n}\n\n/**\n * Copy directory recursively\n */\nasync function copyDirectory(src: string, dst: string): Promise<void> {\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const dstPath = path.join(dst, entry.name);\n\n if (entry.isDirectory()) {\n fs.mkdirSync(dstPath, { recursive: true });\n await copyDirectory(srcPath, dstPath);\n } else {\n const stat = fs.statSync(srcPath);\n fs.copyFileSync(srcPath, dstPath);\n fs.chmodSync(dstPath, stat.mode);\n }\n }\n}\n","/**\n * Template catalog system\n *\n * Fetches and manages template catalog from templates.json\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\n// Environment variable names\nexport const ENV_VAR_USE_LOCAL_TEMPLATES = \"EIGENX_USE_LOCAL_TEMPLATES\";\nexport const ENV_VAR_TEMPLATES_PATH = \"EIGENX_TEMPLATES_PATH\";\n\n// Default repository URL for templates\nexport const DEFAULT_TEMPLATE_REPO = \"https://github.com/Layr-Labs/eigenx-templates\";\n\n// Default version/branch for templates\nexport const DEFAULT_TEMPLATE_VERSION = \"main\";\n\n// Default catalog URL in the eigenx-templates repository\nexport const DEFAULT_CATALOG_URL =\n \"https://raw.githubusercontent.com/Layr-Labs/eigenx-templates/main/templates.json\";\n\n// Cache duration for the catalog (15 minutes)\nexport const CATALOG_CACHE_DURATION = 15 * 60 * 1000; // 15 minutes in milliseconds\n\n/**\n * TemplateEntry represents a single template in the catalog\n */\nexport interface TemplateEntry {\n path: string;\n description: string;\n postProcess?: {\n replaceNameIn?: string[];\n };\n}\n\n/**\n * TemplateCatalog represents the structure of templates.json\n * Organized by language first, then by category (e.g., \"typescript\" -> \"minimal\")\n */\nexport interface TemplateCatalog {\n [language: string]: {\n [category: string]: TemplateEntry;\n };\n}\n\n// In-memory cache\ninterface CatalogCache {\n catalog: TemplateCatalog | null;\n expiresAt: number;\n}\n\nlet cache: CatalogCache = {\n catalog: null,\n expiresAt: 0,\n};\n\n/**\n * Fetch template catalog from remote URL or local file\n * Uses a 15-minute in-memory cache to avoid excessive network requests\n */\nexport async function fetchTemplateCatalog(): Promise<TemplateCatalog> {\n // Check if using local templates\n if (process.env[ENV_VAR_USE_LOCAL_TEMPLATES] === \"true\") {\n return fetchLocalCatalog();\n }\n\n // Check cache first\n if (cache.catalog && Date.now() < cache.expiresAt) {\n return cache.catalog;\n }\n\n // Fetch from remote\n const catalog = await fetchRemoteCatalog(DEFAULT_CATALOG_URL);\n\n // Update cache\n cache.catalog = catalog;\n cache.expiresAt = Date.now() + CATALOG_CACHE_DURATION;\n\n return catalog;\n}\n\n/**\n * Fetch catalog from remote URL\n */\nasync function fetchRemoteCatalog(url: string): Promise<TemplateCatalog> {\n const response = await fetch(url, {\n signal: AbortSignal.timeout(10000), // 10 second timeout\n });\n\n if (!response.ok) {\n throw new Error(`Failed to fetch template catalog: HTTP ${response.status}`);\n }\n\n const data = await response.json();\n return data as TemplateCatalog;\n}\n\n/**\n * Fetch local catalog from templates.json file\n */\nfunction fetchLocalCatalog(): TemplateCatalog {\n // Look for EIGENX_TEMPLATES_PATH first\n let templatesPath = process.env[ENV_VAR_TEMPLATES_PATH];\n\n if (!templatesPath) {\n // Look for eigenx-templates directory as a sibling\n const cwd = process.cwd();\n const possiblePaths = [\n path.join(cwd, \"eigenx-templates\"),\n path.join(path.dirname(cwd), \"eigenx-templates\"),\n ];\n\n for (const possiblePath of possiblePaths) {\n if (fs.existsSync(possiblePath)) {\n templatesPath = possiblePath;\n break;\n }\n }\n\n if (!templatesPath) {\n throw new Error(\n \"Local templates directory not found. Set EIGENX_TEMPLATES_PATH or ensure eigenx-templates is a sibling directory\",\n );\n }\n }\n\n const catalogPath = path.join(templatesPath, \"templates.json\");\n if (!fs.existsSync(catalogPath)) {\n throw new Error(`Local template catalog not found at ${catalogPath}`);\n }\n\n const data = fs.readFileSync(catalogPath, \"utf-8\");\n return JSON.parse(data) as TemplateCatalog;\n}\n\n/**\n * Get template entry by language and category\n */\nexport function getTemplate(\n catalog: TemplateCatalog,\n category: string,\n language: string,\n): TemplateEntry {\n const templates = catalog[language];\n if (!templates) {\n throw new Error(`Language \"${language}\" not found in catalog`);\n }\n\n const template = templates[category];\n if (!template) {\n throw new Error(`Category \"${category}\" not found for language \"${language}\"`);\n }\n\n return template;\n}\n\n/**\n * Get category descriptions for a given language\n */\nexport function getCategoryDescriptions(\n catalog: TemplateCatalog,\n language: string,\n): Record<string, string> {\n const templates = catalog[language];\n if (!templates) {\n return {};\n }\n\n const descriptions: Record<string, string> = {};\n for (const [category, template] of Object.entries(templates)) {\n descriptions[category] = template.description || \"\";\n }\n\n return descriptions;\n}\n","/**\n * Git template fetching\n *\n * Fetches templates from Git repositories\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as os from \"os\";\nimport { exec, execFile } from \"child_process\";\nimport { promisify } from \"util\";\nimport { Logger } from \"../types\";\n\nconst execAsync = promisify(exec);\nconst execFileAsync = promisify(execFile);\n\nexport interface GitFetcherConfig {\n verbose: boolean;\n}\n\n/**\n * Fetch full template repository\n */\nexport async function fetchTemplate(\n repoURL: string,\n ref: string,\n targetDir: string,\n config: GitFetcherConfig,\n logger: Logger,\n): Promise<void> {\n if (!repoURL) {\n throw new Error(\"repoURL is required\");\n }\n\n logger.info(`\\nCloning repo: ${repoURL} → ${targetDir}\\n`);\n\n try {\n // Clone with no checkout\n await execAsync(`git clone --no-checkout --progress ${repoURL} ${targetDir}`, {\n maxBuffer: 10 * 1024 * 1024,\n });\n\n // Checkout the desired ref\n await execFileAsync(\"git\", [\"-C\", targetDir, \"checkout\", \"--quiet\", ref], {\n maxBuffer: 10 * 1024 * 1024,\n });\n\n // Update submodules\n await execFileAsync(\n \"git\",\n [\"-C\", targetDir, \"submodule\", \"update\", \"--init\", \"--recursive\", \"--progress\"],\n { maxBuffer: 10 * 1024 * 1024 },\n );\n\n logger.info(`Clone repo complete: ${repoURL}\\n`);\n } catch (error: any) {\n throw new Error(`Failed to clone repository: ${error.message}`);\n }\n}\n\n/**\n * Fetch subdirectory from template repository using sparse checkout\n */\nexport async function fetchTemplateSubdirectory(\n repoURL: string,\n ref: string,\n subPath: string,\n targetDir: string,\n logger: Logger,\n): Promise<void> {\n if (!repoURL) {\n throw new Error(\"repoURL is required\");\n }\n if (!subPath) {\n throw new Error(\"subPath is required\");\n }\n\n // Create temporary directory for sparse clone\n let tempDir: string;\n try {\n tempDir = fs.mkdtempSync(path.join(os.tmpdir(), \"eigenx-template-\"));\n } catch {\n // If that fails, try ~/.eigenx/tmp\n const homeDir = os.homedir();\n const fallbackBase = path.join(homeDir, \".eigenx\", \"tmp\");\n fs.mkdirSync(fallbackBase, { recursive: true });\n tempDir = fs.mkdtempSync(path.join(fallbackBase, \"eigenx-template-\"));\n }\n\n try {\n logger.info(`\\nCloning template: ${repoURL} → extracting ${subPath}\\n`);\n\n // Clone with sparse checkout\n await cloneSparse(repoURL, ref, subPath, tempDir);\n\n // Verify subdirectory exists\n const srcPath = path.join(tempDir, subPath);\n if (!fs.existsSync(srcPath)) {\n throw new Error(`Template subdirectory ${subPath} not found in ${repoURL}`);\n }\n\n // Copy subdirectory contents to target\n await copyDirectory(srcPath, targetDir);\n\n logger.info(`Template extraction complete: ${subPath}\\n`);\n } finally {\n // Cleanup temp directory\n fs.rmSync(tempDir, { recursive: true, force: true });\n }\n}\n\n/**\n * Clone repository with sparse checkout\n */\nasync function cloneSparse(\n repoURL: string,\n ref: string,\n subPath: string,\n tempDir: string,\n // config: GitFetcherConfig\n): Promise<void> {\n try {\n // Initialize git repository\n await execFileAsync(\"git\", [\"init\", tempDir]);\n\n // Add remote\n await execFileAsync(\"git\", [\"-C\", tempDir, \"remote\", \"add\", \"origin\", repoURL]);\n\n // Enable sparse checkout\n await execFileAsync(\"git\", [\"-C\", tempDir, \"config\", \"core.sparseCheckout\", \"true\"]);\n\n // Set sparse checkout path\n const sparseCheckoutPath = path.join(tempDir, \".git/info/sparse-checkout\");\n fs.writeFileSync(sparseCheckoutPath, `${subPath}\\n`);\n\n // Fetch and checkout\n await execFileAsync(\"git\", [\"-C\", tempDir, \"fetch\", \"origin\", ref]);\n\n await execFileAsync(\"git\", [\"-C\", tempDir, \"checkout\", ref]);\n } catch (error: any) {\n throw new Error(`Failed to clone sparse repository: ${error.message}`);\n }\n}\n\n/**\n * Copy directory recursively\n */\nasync function copyDirectory(src: string, dst: string): Promise<void> {\n const entries = fs.readdirSync(src, { withFileTypes: true });\n\n for (const entry of entries) {\n const srcPath = path.join(src, entry.name);\n const dstPath = path.join(dst, entry.name);\n\n if (entry.isDirectory()) {\n fs.mkdirSync(dstPath, { recursive: true });\n await copyDirectory(srcPath, dstPath);\n } else {\n const stat = fs.statSync(srcPath);\n fs.copyFileSync(srcPath, dstPath);\n fs.chmodSync(dstPath, stat.mode);\n }\n }\n}\n","/**\n * Template post-processing\n *\n * Updates template files with project-specific values\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport { Logger } from \"../types\";\nimport { TemplateEntry } from \"./catalog\";\nimport { getDirname } from \"../utils/dirname\";\n\n// Config file paths\nconst __dirname = getDirname();\nconst CONFIG_DIR = path.join(__dirname, \"../../config\");\n\n/**\n * Post-process template files\n */\nexport async function postProcessTemplate(\n projectDir: string,\n language: string,\n templateEntry: TemplateEntry,\n logger: Logger,\n): Promise<void> {\n const projectName = path.basename(projectDir);\n const templateName = `eigenx-tee-${language}-app`;\n\n // 1. Copy .gitignore\n await copyGitignore(projectDir);\n\n // 2. Copy shared template files (.env.example, README.md)\n await copySharedTemplateFiles(projectDir);\n\n // 3. Get files to update from template metadata, fallback to just README.md\n const filesToUpdate = templateEntry.postProcess?.replaceNameIn || [\"README.md\"];\n\n // 4. Update all files specified in template metadata\n for (const filename of filesToUpdate) {\n await updateProjectFile(projectDir, filename, templateName, projectName, logger);\n }\n}\n\n/**\n * Copy .gitignore from config\n */\nasync function copyGitignore(projectDir: string): Promise<void> {\n const destPath = path.join(projectDir, \".gitignore\");\n\n // Check if .gitignore already exists\n if (fs.existsSync(destPath)) {\n return; // File already exists, skip copying\n }\n\n // Load from config directory\n const gitignorePath = path.join(CONFIG_DIR, \".gitignore\");\n if (fs.existsSync(gitignorePath)) {\n fs.copyFileSync(gitignorePath, destPath);\n } else {\n // Fallback to default gitignore content\n const defaultGitignore = `# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Build outputs\n/bin/\n/out/\n\n# OS-specific files\n.DS_Store\nThumbs.db\n\n# Editor and IDE files\n.vscode/\n.idea/\n*.swp\n\n# Environment\n.env\n\n# Language-specific build outputs\nnode_modules/\ndist/\nbuild/\ntarget/\n__pycache__/\n*.pyc\n`;\n fs.writeFileSync(destPath, defaultGitignore, { mode: 0o644 });\n }\n}\n\n/**\n * Copy shared template files\n */\nasync function copySharedTemplateFiles(projectDir: string): Promise<void> {\n // Write .env.example\n const envPath = path.join(projectDir, \".env.example\");\n const envExamplePath = path.join(CONFIG_DIR, \".env.example\");\n if (fs.existsSync(envExamplePath)) {\n fs.copyFileSync(envExamplePath, envPath);\n } else {\n // Fallback to default .env.example\n const defaultEnvExample = `# Environment variables\n# Variables ending with _PUBLIC will be visible on-chain\n# All other variables will be encrypted\n\n# Example public variable\n# API_URL_PUBLIC=https://api.example.com\n\n# Example private variable\n# SECRET_KEY=your-secret-key-here\n`;\n fs.writeFileSync(envPath, defaultEnvExample, { mode: 0o644 });\n }\n\n // Write or append README.md\n const readmePath = path.join(projectDir, \"README.md\");\n const readmeConfigPath = path.join(CONFIG_DIR, \"README.md\");\n\n if (fs.existsSync(readmePath)) {\n // README.md exists, append the content\n const readmeContent = fs.existsSync(readmeConfigPath)\n ? fs.readFileSync(readmeConfigPath, \"utf-8\")\n : getDefaultReadme();\n fs.appendFileSync(readmePath, \"\\n\" + readmeContent);\n } else {\n // README.md doesn't exist, create it\n const readmeContent = fs.existsSync(readmeConfigPath)\n ? fs.readFileSync(readmeConfigPath, \"utf-8\")\n : getDefaultReadme();\n fs.writeFileSync(readmePath, readmeContent, { mode: 0o644 });\n }\n}\n\n/**\n * Get default README content\n */\nfunction getDefaultReadme(): string {\n return `## Prerequisites\n\nBefore deploying, you'll need:\n\n- **Docker** - To package and publish your application image\n- **ETH** - To pay for deployment transactions\n\n## Deployment\n\n\\`\\`\\`bash\necloud compute app deploy username/image-name\n\\`\\`\\`\n\nThe CLI will automatically detect the \\`Dockerfile\\` and build your app before deploying.\n\n## Management & Monitoring\n\n\\`\\`\\`bash\necloud compute app list # List all apps\necloud compute app info [app-name] # Get app details\necloud compute app logs [app-name] # View logs\necloud compute app start [app-name] # Start stopped app\necloud compute app stop [app-name] # Stop running app\necloud compute app terminate [app-name] # Terminate app\necloud compute app upgrade [app-name] [image] # Update deployment\n\\`\\`\\`\n`;\n}\n\n/**\n * Update project file by replacing template name with project name\n */\nasync function updateProjectFile(\n projectDir: string,\n filename: string,\n oldString: string,\n newString: string,\n logger: Logger,\n): Promise<void> {\n const filePath = path.join(projectDir, filename);\n\n // Check if file exists\n if (!fs.existsSync(filePath)) {\n logger.debug(`File ${filename} not found, skipping update`);\n return;\n }\n\n // Read current file\n const content = fs.readFileSync(filePath, \"utf-8\");\n\n // Replace the specified string\n const newContent = content.replaceAll(oldString, newString);\n\n // Write back to file\n fs.writeFileSync(filePath, newContent, { mode: 0o644 });\n}\n","/**\n * Logs command\n *\n * View app logs with optional watch mode\n *\n * NOTE: This SDK function is non-interactive. All required parameters must be\n * provided explicitly. Use the CLI for interactive parameter collection.\n */\n\nimport { Address } from \"viem\";\nimport { Logger } from \"../../../common/types\";\nimport { defaultLogger } from \"../../../common/utils\";\nimport { UserApiClient } from \"../../../common/utils/userapi\";\nimport { getEnvironmentConfig } from \"../../../common/config/environment\";\nimport { validateAppID } from \"../../../common/utils/validation\";\nimport { withSDKTelemetry } from \"../../../common/telemetry/wrapper\";\nimport chalk from \"chalk\";\n\n/**\n * Required logs options for SDK (non-interactive)\n */\nexport interface SDKLogsOptions {\n /** App ID (address) or app name - required */\n appID: string | Address;\n /** Watch logs continuously - optional */\n watch?: boolean;\n /** Environment name - optional, defaults to 'sepolia' */\n environment?: string;\n /** Private key for authenticated requests - optional */\n privateKey?: string;\n /** RPC URL - optional, uses environment default */\n rpcUrl?: string;\n /** Client ID for API requests - optional */\n clientId?: string;\n /** Skip telemetry (for CLI usage) - optional */\n skipTelemetry?: boolean;\n}\n\n/**\n * Legacy interface for backward compatibility\n * @deprecated Use SDKLogsOptions instead\n */\nexport interface LogsOptions {\n appID?: string | Address;\n watch?: boolean;\n environment?: string;\n privateKey?: string;\n rpcUrl?: string;\n clientId?: string;\n}\n\n// App status constants\nconst AppStatusCreated = \"Created\";\nconst AppStatusDeploying = \"Deploying\";\nconst AppStatusUpgrading = \"Upgrading\";\nconst AppStatusResuming = \"Resuming\";\nconst AppStatusStopping = \"Stopping\";\nconst AppStatusStopped = \"Stopped\";\nconst AppStatusTerminating = \"Terminating\";\nconst AppStatusTerminated = \"Terminated\";\nconst AppStatusSuspended = \"Suspended\";\nconst AppStatusFailed = \"Failed\";\n\n// Watch poll interval\nconst WATCH_POLL_INTERVAL_SECONDS = 5;\n\n/**\n * Format app display\n */\nfunction formatAppDisplay(environmentName: string, appID: Address, profileName: string): string {\n if (profileName) {\n return `${profileName} (${environmentName}:${appID})`;\n }\n return `${environmentName}:${appID}`;\n}\n\n/**\n * Show countdown for watch mode\n * Shows countdown from seconds down to 0, one second at a time\n */\nasync function showCountdown(seconds: number, shouldStop: () => boolean): Promise<void> {\n for (let i = seconds; i >= 0; i--) {\n if (shouldStop()) {\n return;\n }\n process.stdout.write(chalk.gray(`\\rRefreshing in ${i}...`));\n if (i > 0) {\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n}\n\n/**\n * Watch logs continuously\n */\nasync function watchLogs(\n appID: Address,\n userApiClient: UserApiClient,\n initialLogs: string,\n): Promise<void> {\n const tailSize = 65536; // 64KB\n\n // Track previously seen logs\n let prevLogs = initialLogs;\n\n // Handle graceful shutdown\n let shouldStop = false;\n const stopHandler = () => {\n shouldStop = true;\n };\n process.on(\"SIGINT\", stopHandler);\n process.on(\"SIGTERM\", stopHandler);\n\n try {\n while (!shouldStop) {\n // Show countdown\n await showCountdown(WATCH_POLL_INTERVAL_SECONDS, () => shouldStop);\n\n if (shouldStop) {\n break;\n }\n\n // Fetch fresh logs\n let newLogs: string;\n try {\n newLogs = await userApiClient.getLogs(appID);\n } catch {\n // Silently continue on error in watch mode\n continue;\n }\n\n // Skip if no new logs\n if (newLogs === prevLogs) {\n continue;\n }\n\n // Clear the countdown line\n process.stdout.write(\"\\r\\x1b[K\");\n\n if (newLogs.startsWith(prevLogs)) {\n // Normal append - show only new content\n const newContent = newLogs.slice(prevLogs.length);\n process.stdout.write(newContent);\n } else {\n // Check if logs were truncated (old tail matches somewhere in new)\n const tail = prevLogs.slice(Math.max(0, prevLogs.length - tailSize)); // Last 64KB\n const idx = newLogs.lastIndexOf(tail);\n if (idx !== -1) {\n // Found the tail at position idx\n // Print everything after where the old logs ended\n process.stdout.write(newLogs.slice(idx + tail.length));\n } else {\n if (newLogs.length < prevLogs.length) {\n console.log(\"--- Logs restarted ---\");\n } else {\n console.log(\"--- Log stream gap detected ---\");\n }\n process.stdout.write(newLogs);\n }\n }\n // Reset any incomplete formatting/special chars and add blank line\n process.stdout.write(\"\\x1b[0m\");\n console.log();\n prevLogs = newLogs;\n }\n } finally {\n process.removeListener(\"SIGINT\", stopHandler);\n process.removeListener(\"SIGTERM\", stopHandler);\n }\n\n console.log(\"\\nStopped watching\");\n}\n\n/**\n * View app logs\n *\n * This function is non-interactive and requires appID to be provided explicitly.\n *\n * @param options - Required options including appID\n * @param logger - Optional logger instance\n * @throws Error if appID is missing or invalid\n */\nexport async function logs(\n options: SDKLogsOptions | LogsOptions,\n logger: Logger = defaultLogger,\n skipTelemetry: boolean = false,\n): Promise<void> {\n const skipTelemetryFlag = skipTelemetry || (options as SDKLogsOptions).skipTelemetry || false;\n\n return withSDKTelemetry(\n {\n functionName: \"logs\",\n skipTelemetry: skipTelemetryFlag,\n properties: { environment: (options.environment || \"sepolia\") as string },\n },\n async () => {\n console.log();\n\n // Validate required parameters\n if (!options.appID) {\n throw new Error(\"appID is required for viewing logs\");\n }\n\n // Get environment config\n const environment = options.environment || \"sepolia\";\n const environmentConfig = getEnvironmentConfig(environment);\n\n // Get RPC URL (needed for contract queries and authentication)\n const rpcUrl = options.rpcUrl || environmentConfig.defaultRPCURL;\n if (!rpcUrl) {\n throw new Error(\"RPC URL is required for authenticated requests\");\n }\n\n // Validate app ID (must be a valid address - name resolution is done by CLI)\n const appID = validateAppID(options.appID);\n\n // Format app display (no profile name in SDK - CLI handles that)\n const formattedApp = formatAppDisplay(environmentConfig.name, appID, \"\");\n\n // Create user API client\n const userApiClient = new UserApiClient(\n environmentConfig,\n options.privateKey,\n rpcUrl,\n options.clientId,\n );\n\n // Fetch logs\n let logsText: string;\n let logsError: Error | null = null;\n try {\n logsText = await userApiClient.getLogs(appID);\n } catch (err: any) {\n logsError = err;\n logsText = \"\";\n }\n\n const watchMode = options.watch || false;\n\n // Handle empty logs or errors\n if (logsError || logsText.trim() === \"\") {\n // If watch mode is enabled, enter watch loop even without initial logs\n if (watchMode) {\n logger.info(\"\\nWaiting for logs to become available...\");\n console.log();\n await watchLogs(appID, userApiClient, \"\");\n return;\n }\n\n // Not watch mode - check app status to provide helpful message and exit\n try {\n const statuses = await userApiClient.getStatuses([appID]);\n if (statuses.length > 0) {\n const status = statuses[0].status;\n switch (status) {\n case AppStatusCreated:\n case AppStatusDeploying:\n logger.info(\n `${formattedApp} is currently being provisioned. Logs will be available once deployment is complete.`,\n );\n return;\n case AppStatusUpgrading:\n logger.info(\n `${formattedApp} is currently upgrading. Logs will be available once upgrade is complete.`,\n );\n return;\n case AppStatusResuming:\n logger.info(\n `${formattedApp} is currently resuming. Logs will be available shortly.`,\n );\n return;\n case AppStatusStopping:\n logger.info(`${formattedApp} is currently stopping. Logs may be limited.`);\n return;\n case AppStatusStopped:\n case AppStatusTerminating:\n case AppStatusTerminated:\n case AppStatusSuspended:\n logger.info(`${formattedApp} is ${status.toLowerCase()}. Logs are not available.`);\n return;\n case AppStatusFailed:\n logger.info(\n `${formattedApp} has failed. Check the app status for more information.`,\n );\n return;\n }\n }\n } catch {\n // If we can't get status either, continue to error handling\n }\n\n // If we can't get status either, return the original logs error\n if (logsError) {\n throw new Error(\n `Failed to get logs, you can watch for logs by calling this command with the --watch flag (or --w): ${logsError.message}`,\n );\n }\n throw new Error(\n \"Failed to get logs, you can watch for logs by calling this command with the --watch flag (or --w): empty logs\",\n );\n }\n\n // Print initial logs\n console.log(logsText);\n\n // Check if watch mode is enabled\n if (!watchMode) {\n return;\n }\n\n // Watch mode: continuously fetch and display new logs\n await watchLogs(appID, userApiClient, logsText);\n },\n );\n}\n","/**\n * Main Compute namespace entry point\n */\n\nimport { Hex } from \"viem\";\nimport { createAppModule, type AppModule } from \"./app\";\n\nexport interface ComputeModule {\n app: AppModule;\n}\n\nexport interface ComputeModuleConfig {\n verbose?: boolean;\n privateKey: Hex;\n rpcUrl: string;\n environment: string;\n clientId?: string;\n skipTelemetry?: boolean;\n}\n\nexport function createComputeModule(config: ComputeModuleConfig): ComputeModule {\n return {\n app: createAppModule(config),\n };\n}\n\n// Re-export app module for standalone use\nexport { createAppModule, type AppModule, type AppModuleConfig } from \"./app\";\n\n// Re-export app module utilities\nexport { encodeStartAppData, encodeStopAppData, encodeTerminateAppData } from \"./app\";\n"],"mappings":"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","names":["import_viem","import_accounts","exec","resolve","process","path","platform","resolve","err","child_process","import_util","resolve","process","Handlebars","import_handlebars","Handlebars","kms_encryption_public_key_default","kms_signing_public_key_default","kms_encryption_public_key_default","kms_signing_public_key_default","kms_encryption_public_key_default","kms_signing_public_key_default","__dirname","Docker","child_process","import_util","execFileAsync","platform","fs","resolve","import_accounts","isDelegated","import_viem","import_accounts","import_viem","import_viem","import_viem","import_chains","FormData","fs","path","axios","resolve","import_viem","fs","import_viem","import_accounts","os","import_viem","CanViewAppLogsPermission","fs","path","fs","path","fs","path","os","import_child_process","import_util","execFileAsync","fs","path","__dirname","copyDirectory","WATCH_POLL_INTERVAL_SECONDS","chalk","resolve"]}
|