@layr-labs/ecloud-sdk 0.2.0 → 0.2.1-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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client/common/config/environment.ts","../src/client/common/utils/validation.ts","../src/client/common/utils/helpers.ts","../src/client/common/constants.ts","../src/client/common/utils/billing.ts","../src/client/common/auth/generate.ts","../src/client/common/utils/userapi.ts","../src/client/common/utils/auth.ts","../src/client/common/contract/eip7702.ts","../src/client/common/abis/ERC7702Delegator.json","../src/client/common/contract/caller.ts","../src/client/common/abis/AppController.json","../src/client/common/contract/encoders.ts"],"sourcesContent":["/**\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 * 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, \"&amp;\")\n .replace(/</g, \"&lt;\")\n .replace(/>/g, \"&gt;\")\n .replace(/\"/g, \"&quot;\")\n .replace(/'/g, \"&#39;\");\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 * General utility helpers\n */\n\nimport { extractChain, createPublicClient, createWalletClient, http } from \"viem\";\nimport type { Chain, Hex, PublicClient, WalletClient } from \"viem\";\nimport { sepolia } from \"viem/chains\";\nimport { privateKeyToAccount } from \"viem/accounts\";\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 * Create viem clients from a private key\n *\n * This is a convenience helper for CLI and server applications that have direct\n * access to a private key. For browser applications using external wallets (MetaMask, etc.),\n * create the WalletClient directly using viem's createWalletClient with a custom transport.\n *\n * @example\n * // CLI usage with private key\n * const { walletClient, publicClient } = createClients({\n * privateKey: '0x...',\n * rpcUrl: 'https://sepolia.infura.io/v3/...',\n * chainId: 11155111n\n * });\n *\n * @example\n * // Browser usage with external wallet (create clients directly)\n * const walletClient = createWalletClient({\n * chain: sepolia,\n * transport: custom(window.ethereum!)\n * });\n * const publicClient = createPublicClient({\n * chain: sepolia,\n * transport: custom(window.ethereum!)\n * });\n */\nexport function createClients(options: {\n privateKey: string | Hex;\n rpcUrl: string;\n chainId: bigint;\n}): {\n walletClient: WalletClient;\n publicClient: PublicClient;\n} {\n const { privateKey, rpcUrl, chainId } = options;\n\n const privateKeyHex = addHexPrefix(privateKey);\n const account = privateKeyToAccount(privateKeyHex);\n const chain = getChainFromID(chainId);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n });\n\n const walletClient = createWalletClient({\n account,\n chain,\n transport: http(rpcUrl),\n });\n\n return { walletClient, publicClient };\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 * 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 * Billing utility functions\n */\n\nimport type { SubscriptionStatus } from \"../types\";\n\n/**\n * Check if subscription status allows deploying apps\n */\nexport function isSubscriptionActive(status: SubscriptionStatus): boolean {\n return status === \"active\" || status === \"trialing\";\n}\n","/**\n * Private Key Generation\n *\n * Generate new secp256k1 private keys for Ethereum\n */\n\nimport { generatePrivateKey, privateKeyToAddress } from \"viem/accounts\";\n\nexport interface GeneratedKey {\n privateKey: string;\n address: string;\n}\n\n/**\n * Generate a new secp256k1 private key\n */\nexport function generateNewPrivateKey(): GeneratedKey {\n const privateKey = generatePrivateKey();\n const address = privateKeyToAddress(privateKey);\n\n return {\n privateKey,\n address,\n };\n}\n","import axios, { AxiosResponse } from \"axios\";\nimport { Address, Hex, type PublicClient, type WalletClient } from \"viem\";\nimport { calculatePermissionSignature } from \"./auth\";\nimport { EnvironmentConfig } from \"../types\";\nimport { stripHexPrefix } 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\n// ==================== App Releases (/apps/:id) ====================\n\ntype JsonObject = Record<string, unknown>;\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction readString(obj: JsonObject, key: string): string | undefined {\n const v = obj[key];\n return typeof v === \"string\" ? v : undefined;\n}\n\nfunction readNumber(obj: JsonObject, key: string): number | undefined {\n const v = obj[key];\n return typeof v === \"number\" && Number.isFinite(v) ? v : undefined;\n}\n\nexport type AppContractStatus = \"STARTED\" | \"STOPPED\" | \"TERMINATED\" | \"SUSPENDED\" | string;\n\nexport interface AppReleaseBuild {\n buildId?: string;\n billingAddress?: string;\n repoUrl?: string;\n gitRef?: string;\n status?: string;\n buildType?: string;\n imageName?: string;\n imageDigest?: string;\n imageUrl?: string;\n provenanceJson?: unknown;\n provenanceSignature?: string;\n createdAt?: string;\n updatedAt?: string;\n errorMessage?: string;\n dependencies?: Record<string, AppReleaseBuild>;\n}\n\nexport interface AppRelease {\n appId?: string;\n rmsReleaseId?: string;\n imageDigest?: string;\n registryUrl?: string;\n publicEnv?: string;\n encryptedEnv?: string;\n upgradeByTime?: number;\n createdAt?: string;\n createdAtBlock?: string;\n build?: AppReleaseBuild;\n}\n\nexport interface AppResponse {\n id: string;\n creator?: string;\n contractStatus?: AppContractStatus;\n releases: AppRelease[];\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\n/**\n * UserAPI Client for interacting with the EigenCloud UserAPI service.\n */\nexport class UserApiClient {\n private readonly clientId: string;\n\n constructor(\n private readonly config: EnvironmentConfig,\n private readonly walletClient: WalletClient,\n private readonly publicClient: PublicClient,\n clientId?: string,\n ) {\n this.clientId = clientId || getDefaultClientId();\n }\n\n /**\n * Get the address of the connected wallet\n */\n get address(): Address {\n const account = this.walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n return account.address;\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 app details from UserAPI (includes releases and build/provenance info when available).\n *\n * Endpoint: GET /apps/:appAddress\n */\n async getApp(appAddress: Address): Promise<AppResponse> {\n const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}`;\n const res = await this.makeAuthenticatedRequest(endpoint);\n const raw = (await res.json()) as unknown;\n\n if (!isJsonObject(raw)) {\n throw new Error(\"Unexpected /apps/:id response: expected object\");\n }\n\n const id = readString(raw, \"id\");\n if (!id) {\n throw new Error(\"Unexpected /apps/:id response: missing 'id'\");\n }\n\n const releasesRaw = raw.releases;\n const releases = Array.isArray(releasesRaw)\n ? releasesRaw.map((r) => transformAppRelease(r)).filter((r): r is AppRelease => !!r)\n : [];\n\n return {\n id,\n creator: readString(raw, \"creator\"),\n contractStatus: (readString(raw, \"contract_status\") ?? readString(raw, \"contractStatus\")) as\n | AppContractStatus\n | undefined,\n releases,\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 * @param appAddress - The app's contract address\n * @param name - Display name for the app\n * @param options - Optional fields including website, description, xURL, and image\n * @param options.image - Image file as Blob or File (browser: from input element, Node.js: new Blob([buffer]))\n * @param options.imageName - Filename for the image (required if image is provided)\n */\n async uploadAppProfile(\n appAddress: Address,\n name: string,\n options?: {\n website?: string;\n description?: string;\n xURL?: string;\n image?: Blob | File;\n imageName?: string;\n },\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 Web FormData API (works in browser and Node.js 18+)\n const formData = new FormData();\n\n // Add required name field\n formData.append(\"name\", name);\n\n // Add optional text fields\n if (options?.website) {\n formData.append(\"website\", options.website);\n }\n if (options?.description) {\n formData.append(\"description\", options.description);\n }\n if (options?.xURL) {\n formData.append(\"xURL\", options.xURL);\n }\n\n // Add optional image file (Blob or File)\n if (options?.image) {\n // If it's a File, use its name; otherwise require imageName\n const fileName =\n options.image instanceof File ? options.image.name : options.imageName || \"image\";\n formData.append(\"image\", options.image, fileName);\n }\n\n // Make authenticated POST request\n // Note: Don't set Content-Type header manually - axios will set it with the correct boundary\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n };\n\n // Add auth headers (Authorization and X-eigenx-expiry)\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 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) {\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 // Calculate permission signature using shared auth utility\n const { signature } = await calculatePermissionSignature({\n permission,\n expiry,\n appControllerAddress: this.config.appControllerAddress,\n publicClient: this.publicClient,\n walletClient: this.walletClient,\n });\n\n // Return auth headers\n return {\n Authorization: `Bearer ${stripHexPrefix(signature)}`,\n \"X-eigenx-expiry\": expiry.toString(),\n };\n }\n}\n\nfunction transformAppReleaseBuild(raw: unknown): AppReleaseBuild | undefined {\n if (!isJsonObject(raw)) return undefined;\n\n const depsRaw = raw.dependencies;\n const deps: Record<string, AppReleaseBuild> | undefined = isJsonObject(depsRaw)\n ? Object.fromEntries(\n Object.entries(depsRaw).flatMap(([digest, depRaw]) => {\n const parsed = transformAppReleaseBuild(depRaw);\n return parsed ? ([[digest, parsed]] as const) : [];\n }),\n )\n : undefined;\n\n return {\n buildId: readString(raw, \"build_id\") ?? readString(raw, \"buildId\"),\n billingAddress: readString(raw, \"billing_address\") ?? readString(raw, \"billingAddress\"),\n repoUrl: readString(raw, \"repo_url\") ?? readString(raw, \"repoUrl\"),\n gitRef: readString(raw, \"git_ref\") ?? readString(raw, \"gitRef\"),\n status: readString(raw, \"status\"),\n buildType: readString(raw, \"build_type\") ?? readString(raw, \"buildType\"),\n imageName: readString(raw, \"image_name\") ?? readString(raw, \"imageName\"),\n imageDigest: readString(raw, \"image_digest\") ?? readString(raw, \"imageDigest\"),\n imageUrl: readString(raw, \"image_url\") ?? readString(raw, \"imageUrl\"),\n provenanceJson: raw.provenance_json ?? raw.provenanceJson,\n provenanceSignature:\n readString(raw, \"provenance_signature\") ?? readString(raw, \"provenanceSignature\"),\n createdAt: readString(raw, \"created_at\") ?? readString(raw, \"createdAt\"),\n updatedAt: readString(raw, \"updated_at\") ?? readString(raw, \"updatedAt\"),\n errorMessage: readString(raw, \"error_message\") ?? readString(raw, \"errorMessage\"),\n dependencies: deps,\n };\n}\n\nfunction transformAppRelease(raw: unknown): AppRelease | undefined {\n if (!isJsonObject(raw)) return undefined;\n\n return {\n appId: readString(raw, \"appId\") ?? readString(raw, \"app_id\"),\n rmsReleaseId: readString(raw, \"rmsReleaseId\") ?? readString(raw, \"rms_release_id\"),\n imageDigest: readString(raw, \"imageDigest\") ?? readString(raw, \"image_digest\"),\n registryUrl: readString(raw, \"registryUrl\") ?? readString(raw, \"registry_url\"),\n publicEnv: readString(raw, \"publicEnv\") ?? readString(raw, \"public_env\"),\n encryptedEnv: readString(raw, \"encryptedEnv\") ?? readString(raw, \"encrypted_env\"),\n upgradeByTime: readNumber(raw, \"upgradeByTime\") ?? readNumber(raw, \"upgrade_by_time\"),\n createdAt: readString(raw, \"createdAt\") ?? readString(raw, \"created_at\"),\n createdAtBlock: readString(raw, \"createdAtBlock\") ?? readString(raw, \"created_at_block\"),\n build: raw.build ? transformAppReleaseBuild(raw.build) : undefined,\n };\n}\n","/**\n * Shared authentication utilities for API clients\n */\n\nimport { Hex, parseAbi, type Address, type PublicClient, type WalletClient } 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: PublicClient;\n walletClient: WalletClient;\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 *\n * Works with any WalletClient - whether backed by a local private key or external signer.\n */\nexport async function calculatePermissionSignature(\n options: PermissionSignatureOptions,\n): Promise<PermissionSignatureResult> {\n const { permission, expiry, appControllerAddress, publicClient, walletClient } = 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 // Get account from wallet client\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n\n // Sign the digest using EIP-191 (signMessage handles prefixing automatically)\n const signature = await walletClient.signMessage({\n account,\n message: { raw: digest },\n });\n\n return { signature, digest };\n}\n\nexport interface BillingAuthSignatureOptions {\n walletClient: WalletClient;\n product: string;\n expiry: bigint;\n}\n\nexport interface BillingAuthSignatureResult {\n signature: Hex;\n expiry: bigint;\n}\n\nconst generateBillingSigData = (product: string, expiry: bigint) => {\n return {\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\" as const,\n message: {\n product,\n expiry,\n },\n };\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 { walletClient, product, expiry } = options;\n\n // Get account from wallet client\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n\n // Sign using EIP-712 typed data\n const signature = await walletClient.signTypedData({\n account,\n ...generateBillingSigData(product, expiry),\n });\n\n return { signature, expiry };\n}\n\nexport interface BuildAuthSignatureOptions {\n walletClient: WalletClient;\n expiry: bigint;\n}\n\nexport interface BuildAuthSignatureResult {\n signature: Hex;\n expiry: bigint;\n}\n\n/**\n * Sign build authentication message using EIP-712 typed data\n */\nexport async function calculateBuildAuthSignature(\n options: BuildAuthSignatureOptions,\n): Promise<BuildAuthSignatureResult> {\n const { walletClient, expiry } = options;\n\n // Get account from wallet client\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n\n const signature = await walletClient.signTypedData({\n account,\n domain: {\n name: \"EigenCloud Build API\",\n version: \"1\",\n },\n types: {\n BuildAuth: [{ name: \"expiry\", type: \"uint256\" }],\n },\n primaryType: \"BuildAuth\",\n message: {\n expiry,\n },\n });\n\n return { signature, expiry };\n}\n","/**\n * EIP-7702 transaction handling\n *\n * This module handles EIP-7702 delegation and batch execution.\n */\n\nimport { Address, Hex, encodeFunctionData, encodeAbiParameters, decodeErrorResult } from \"viem\";\n\nimport type {\n WalletClient,\n PublicClient,\n SendTransactionParameters,\n SignAuthorizationReturnType,\n} from \"viem\";\nimport { EnvironmentConfig, Logger } from \"../types\";\n\nimport ERC7702DelegatorABI from \"../abis/ERC7702Delegator.json\";\n\nimport { GasEstimate, formatETH } from \"./caller\";\n\n// Mode 0x01 is executeBatchMode (32 bytes, padded, big endian)\nconst EXECUTE_BATCH_MODE =\n \"0x0100000000000000000000000000000000000000000000000000000000000000\" as Hex;\n\nconst GAS_LIMIT_BUFFER_PERCENTAGE = 20n; // 20%\nconst GAS_PRICE_BUFFER_PERCENTAGE = 100n; // 100%\n\nexport type Execution = {\n target: Address;\n value: bigint;\n callData: Hex;\n};\n\n/**\n * Encode executions array and pack into execute function call data\n */\nfunction encodeExecuteBatchData(executions: Execution[]): Hex {\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 return encodeFunctionData({\n abi: ERC7702DelegatorABI,\n functionName: \"execute\",\n args: [EXECUTE_BATCH_MODE, encodedExecutions],\n });\n}\n\n/**\n * Options for estimating batch gas\n */\nexport interface EstimateBatchGasOptions {\n publicClient: PublicClient;\n account: Address;\n executions: Execution[];\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 */\nexport async function estimateBatchGas(options: EstimateBatchGasOptions): Promise<GasEstimate> {\n const { publicClient, account, executions } = options;\n\n const executeBatchData = encodeExecuteBatchData(executions);\n\n // EIP-7702 transactions send to self (the EOA with delegated code)\n const [gasTipCap, block, estimatedGas] = await Promise.all([\n publicClient.estimateMaxPriorityFeePerGas(),\n publicClient.getBlock(),\n publicClient.estimateGas({\n account,\n to: account,\n data: executeBatchData,\n }),\n ]);\n\n const baseFee = block.baseFeePerGas ?? 0n;\n\n // Calculate gas price with 100% buffer: (baseFee + gasTipCap) * 2\n const maxFeePerGas = ((baseFee + gasTipCap) * (100n + GAS_PRICE_BUFFER_PERCENTAGE)) / 100n;\n\n // Add 20% buffer to gas limit\n const gasLimit = (estimatedGas * (100n + GAS_LIMIT_BUFFER_PERCENTAGE)) / 100n;\n\n const maxCostWei = gasLimit * maxFeePerGas;\n\n return {\n gasLimit,\n maxFeePerGas,\n maxPriorityFeePerGas: gasTipCap,\n maxCostWei,\n maxCostEth: formatETH(maxCostWei),\n };\n}\n\nexport interface ExecuteBatchOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n executions: Execution[];\n pendingMessage: string;\n /** Optional gas params from estimation */\n gas?: GasEstimate;\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.getCode({ 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 */\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 const executeBatchData = encodeExecuteBatchData(executions);\n\n // 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: Array<SignAuthorizationReturnType> = [];\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 logger.debug(\"Using wallet client signing for EIP-7702 authorization\");\n\n const signedAuthorization = await walletClient.signAuthorization({\n account: account.address,\n contractAddress: environmentConfig.erc7702DelegatorAddress as Address,\n chainId: chainId,\n nonce: Number(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 // eslint-disable-next-line @typescript-eslint/no-explicit-any\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 * Contract interactions\n *\n * This module handles on-chain contract interactions using viem.\n *\n * Accepts viem's WalletClient and PublicClient directly, which abstract over both\n * local accounts (privateKeyToAccount) and external signers (MetaMask, etc.).\n *\n * @example\n * // CLI usage with private key\n * const { walletClient, publicClient } = createClients({ privateKey, rpcUrl, chainId });\n * await deployApp({ walletClient, publicClient, environmentConfig, ... }, logger);\n *\n * @example\n * // Browser usage with external wallet\n * const walletClient = createWalletClient({ chain, transport: custom(window.ethereum!) });\n * const publicClient = createPublicClient({ chain, transport: custom(window.ethereum!) });\n * await deployApp({ walletClient, publicClient, environmentConfig, ... }, logger);\n */\n\nimport { executeBatch, checkERC7702Delegation } from \"./eip7702\";\nimport {\n Address,\n Hex,\n encodeFunctionData,\n decodeErrorResult,\n bytesToHex,\n} from \"viem\";\nimport type { WalletClient, PublicClient } from \"viem\";\n\nimport { EnvironmentConfig, Logger, PreparedDeployData, PreparedUpgradeData } from \"../types\";\nimport { Release } from \"../types\";\nimport { getChainFromID } from \"../utils/helpers\";\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 publicClient: PublicClient;\n from: Address;\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 { publicClient, from, to, data, value = 0n } = options;\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: from,\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\n/**\n * Deploy app options\n */\nexport interface DeployAppOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n salt: Uint8Array;\n release: Release;\n publicLogs: boolean;\n imageRef: string;\n gas?: GasEstimate;\n}\n\n/**\n * Options for calculateAppID\n */\nexport interface CalculateAppIDOptions {\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n ownerAddress: Address;\n salt: Uint8Array;\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(options: CalculateAppIDOptions): Promise<Address> {\n const { publicClient, environmentConfig, ownerAddress, salt } = options;\n\n // Ensure salt is properly formatted as hex string (32 bytes = 64 hex chars)\n // bytesToHex returns 0x-prefixed string, slice(2) removes the prefix for padding\n const saltHexString = bytesToHex(salt).slice(2);\n // Pad to 64 characters if needed\n const paddedSaltHex = saltHexString.padStart(64, \"0\");\n const saltHex = `0x${paddedSaltHex}` as Hex;\n\n const appID = await publicClient.readContract({\n address: environmentConfig.appControllerAddress as Address,\n abi: AppControllerABI,\n functionName: \"calculateAppId\",\n args: [ownerAddress, saltHex],\n });\n\n return appID as Address;\n}\n\n/**\n * Options for preparing a deploy batch\n */\nexport interface PrepareDeployBatchOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n salt: Uint8Array;\n release: Release;\n publicLogs: boolean;\n imageRef: string;\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 { walletClient, publicClient, environmentConfig, salt, release, publicLogs } = options;\n\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n\n // 1. Calculate app ID\n logger.info(\"Calculating app ID...\");\n const appId = await calculateAppID({\n publicClient,\n environmentConfig,\n ownerAddress: account.address,\n salt,\n });\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 = bytesToHex(salt).slice(2);\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${bytesToHex(artifact.digest).slice(2).padStart(64, \"0\")}` as Hex,\n registry: artifact.registry,\n })),\n upgradeByTime: release.rmsRelease.upgradeByTime,\n },\n publicEnv: bytesToHex(release.publicEnv) as Hex,\n encryptedEnv: bytesToHex(release.encryptedEnv) 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: GasEstimate | 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(options, logger);\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\n/**\n * Upgrade app options\n */\nexport interface UpgradeAppOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n appID: Address;\n release: Release;\n publicLogs: boolean;\n needsPermissionChange: boolean;\n imageRef: string;\n gas?: GasEstimate;\n}\n\n/**\n * Options for preparing an upgrade batch\n */\nexport interface PrepareUpgradeBatchOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n appID: Address;\n release: Release;\n publicLogs: boolean;\n needsPermissionChange: boolean;\n imageRef: string;\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 { walletClient, publicClient, environmentConfig, appID, release, publicLogs, needsPermissionChange } = options;\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${bytesToHex(artifact.digest).slice(2).padStart(64, \"0\")}` as Hex,\n registry: artifact.registry,\n })),\n upgradeByTime: release.rmsRelease.upgradeByTime,\n },\n publicEnv: bytesToHex(release.publicEnv) as Hex,\n encryptedEnv: bytesToHex(release.encryptedEnv) 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: 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: GasEstimate | 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(options);\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 walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n to: Address;\n data: Hex;\n value?: bigint;\n pendingMessage: string;\n txDescription: string;\n gas?: GasEstimate;\n}\n\nexport async function sendAndWaitForTransaction(\n options: SendTransactionOptions,\n logger: Logger,\n): Promise<Hex> {\n const { walletClient, publicClient, environmentConfig, to, data, value = 0n, pendingMessage, txDescription, gas } = options;\n\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n\n const chain = getChainFromID(environmentConfig.chainID);\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 && {\n maxPriorityFeePerGas: gas.maxPriorityFeePerGas,\n }),\n chain,\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 publicClient: PublicClient,\n environmentConfig: EnvironmentConfig,\n user: Address,\n): Promise<number> {\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 publicClient: PublicClient,\n environmentConfig: EnvironmentConfig,\n user: Address,\n): Promise<number> {\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 publicClient: PublicClient,\n environmentConfig: EnvironmentConfig,\n creator: Address,\n offset: bigint,\n limit: bigint,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\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 publicClient: PublicClient,\n environmentConfig: EnvironmentConfig,\n developer: Address,\n offset: bigint,\n limit: bigint,\n): Promise<{ apps: Address[]; appConfigs: AppConfig[] }> {\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 publicClient: PublicClient,\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(publicClient, 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 publicClient: PublicClient,\n environmentConfig: EnvironmentConfig,\n appIDs: Address[],\n): Promise<Map<Address, number>> {\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 publicClient: PublicClient,\n blockNumbers: number[],\n): Promise<Map<number, number>> {\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 options\n */\nexport interface SuspendOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n account: Address;\n apps: Address[];\n}\n\n/**\n * Suspend apps for an account\n */\nexport async function suspend(options: SuspendOptions, logger: Logger): Promise<Hex | false> {\n const { walletClient, publicClient, 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 walletClient,\n publicClient,\n environmentConfig,\n to: environmentConfig.appControllerAddress as Address,\n data: suspendData,\n pendingMessage,\n txDescription: \"Suspend\",\n }, logger);\n}\n\n/**\n * Options for checking delegation status\n */\nexport interface IsDelegatedOptions {\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n address: Address;\n}\n\n/**\n * Check if account is delegated to the ERC-7702 delegator\n */\nexport async function isDelegated(options: IsDelegatedOptions): Promise<boolean> {\n const { publicClient, environmentConfig, address } = options;\n\n return checkERC7702Delegation(\n publicClient,\n address,\n environmentConfig.erc7702DelegatorAddress as Address,\n );\n}\n\n/**\n * Undelegate options\n */\nexport interface UndelegateOptions {\n walletClient: WalletClient;\n publicClient: PublicClient;\n environmentConfig: EnvironmentConfig;\n}\n\n/**\n * Undelegate account (removes EIP-7702 delegation)\n */\nexport async function undelegate(options: UndelegateOptions, logger: Logger): Promise<Hex> {\n const { walletClient, publicClient, environmentConfig } = options;\n\n const account = walletClient.account;\n if (!account) {\n throw new Error(\"WalletClient must have an account attached\");\n }\n\n const chain = getChainFromID(environmentConfig.chainID);\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 logger.debug(\"Signing undelegate authorization\");\n\n const signedAuthorization = await walletClient.signAuthorization({\n contractAddress: \"0x0000000000000000000000000000000000000000\" as Address,\n chainId: chainId,\n nonce: Number(authorizationNonce),\n account: account,\n });\n\n const authorizationList = [signedAuthorization];\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 chain,\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 {\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 * Browser-safe app action encoders\n *\n * These functions encode calldata for app lifecycle operations.\n * They only depend on viem and are safe to use in browser environments.\n */\n\nimport { parseAbi, encodeFunctionData } from \"viem\";\nimport type { AppId } from \"../types\";\n\n// Minimal ABI for app lifecycle operations\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 or transaction\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 or transaction\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 or transaction\n */\nexport function encodeTerminateAppData(appId: AppId): `0x${string}` {\n return encodeFunctionData({\n abi: CONTROLLER_ABI,\n functionName: \"terminateApp\",\n args: [appId],\n });\n}\n"],"mappings":"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","names":["sepolia","encodeFunctionData","decodeErrorResult","parseAbi","encodeFunctionData"]}