@layr-labs/ecloud-sdk 0.1.2 → 0.2.0-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/VERSION +2 -2
- package/dist/billing.cjs +1 -1
- package/dist/billing.cjs.map +1 -1
- package/dist/billing.d.cts +1 -1
- package/dist/billing.d.ts +1 -1
- package/dist/billing.js +2 -2
- package/dist/{chunk-AOZRDBLK.js → chunk-FY7UU55U.js} +107 -31
- package/dist/chunk-FY7UU55U.js.map +1 -0
- package/dist/{chunk-4RG5IMZ7.js → chunk-GB4GM4C2.js} +2 -2
- package/dist/{chunk-MQ2NGP4C.js → chunk-O7EU5JL7.js} +312 -55
- package/dist/chunk-O7EU5JL7.js.map +1 -0
- package/dist/{compute-BlUpqWKo.d.cts → compute-CF2HOXed.d.ts} +9 -1
- package/dist/{compute-CottWiST.d.ts → compute-CbmjA8kJ.d.cts} +9 -1
- package/dist/compute.cjs +387 -47
- package/dist/compute.cjs.map +1 -1
- package/dist/compute.d.cts +2 -2
- package/dist/compute.d.ts +2 -2
- package/dist/compute.js +2 -2
- package/dist/{index-Fb_S-Cqk.d.ts → index-D2QufVB9.d.cts} +33 -1
- package/dist/{index-Fb_S-Cqk.d.cts → index-D2QufVB9.d.ts} +33 -1
- package/dist/index.cjs +769 -47
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +314 -98
- package/dist/index.d.ts +314 -98
- package/dist/index.js +376 -3
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/chunk-AOZRDBLK.js.map +0 -1
- package/dist/chunk-MQ2NGP4C.js.map +0 -1
- /package/dist/{chunk-4RG5IMZ7.js.map → chunk-GB4GM4C2.js.map} +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/client/common/config/environment.ts","../src/client/common/utils/helpers.ts","../src/client/common/constants.ts","../src/client/common/utils/userapi.ts","../src/client/common/utils/auth.ts","../src/client/common/utils/billing.ts","../src/client/common/telemetry/noop.ts","../src/client/common/telemetry/posthog.ts","../src/client/common/telemetry/metricsContext.ts","../src/client/common/telemetry/index.ts","../src/client/common/telemetry/wrapper.ts","../src/client/common/utils/logger.ts","../src/client/common/utils/dirname.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 * General utility helpers\n */\n\nimport { extractChain } from \"viem\";\nimport type { Chain, Hex } from \"viem\";\nimport { sepolia } from \"viem/chains\";\nimport { SUPPORTED_CHAINS } from \"../constants\";\n\n/**\n * Get a viem Chain object from a chain ID.\n * Supports mainnet (1) and sepolia (11155111), defaults to the fallback chain for unknown chains.\n */\nexport function getChainFromID(chainID: bigint, fallback: Chain = sepolia): Chain {\n const id = Number(chainID) as (typeof SUPPORTED_CHAINS)[number][\"id\"];\n return extractChain({ chains: SUPPORTED_CHAINS, id }) || fallback;\n}\n\n/**\n * Ensure hex string has 0x prefix\n */\nexport function addHexPrefix(value: string): Hex {\n return (value.startsWith(\"0x\") ? value : `0x${value}`) as Hex;\n}\n\n/**\n * Remove 0x prefix from hex string if present\n */\nexport function stripHexPrefix(value: string): string {\n return value.startsWith(\"0x\") ? value.slice(2) : value;\n}\n","/**\n * 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 * UserAPI Client to manage interactions with the coordinator\n */\n\nimport axios, { AxiosResponse } from \"axios\";\nimport FormData from \"form-data\";\nimport { Address, Hex, createPublicClient, http } from \"viem\";\nimport { calculatePermissionSignature } from \"./auth\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { EnvironmentConfig } from \"../types\";\nimport { addHexPrefix, stripHexPrefix, getChainFromID } from \"./helpers\";\n\nexport interface AppProfileInfo {\n name: string;\n website?: string;\n description?: string;\n xURL?: string;\n imageURL?: string;\n}\n\nexport interface AppMetrics {\n cpu_utilization_percent?: number;\n memory_utilization_percent?: number;\n memory_used_bytes?: number;\n memory_total_bytes?: number;\n}\n\nexport interface DerivedAddress {\n address: string;\n derivationPath: string;\n}\n\nexport interface AppInfo {\n address: Address;\n status: string;\n ip: string;\n machineType: string;\n profile?: AppProfileInfo;\n metrics?: AppMetrics;\n evmAddresses: DerivedAddress[];\n solanaAddresses: DerivedAddress[];\n}\n\nexport interface AppInfoResponse {\n apps: Array<{\n addresses: {\n data: {\n evmAddresses: DerivedAddress[];\n solanaAddresses: DerivedAddress[];\n };\n signature: string;\n };\n app_status: string;\n ip: string;\n machine_type: string;\n profile?: AppProfileInfo;\n metrics?: AppMetrics;\n }>;\n}\n\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\nexport class UserApiClient {\n private readonly account?: ReturnType<typeof privateKeyToAccount>;\n private readonly rpcUrl?: string;\n private readonly clientId: string;\n\n constructor(\n private readonly config: EnvironmentConfig,\n privateKey?: string | Hex,\n rpcUrl?: string,\n clientId?: string,\n ) {\n if (privateKey) {\n const privateKeyHex = addHexPrefix(privateKey);\n this.account = privateKeyToAccount(privateKeyHex);\n }\n this.rpcUrl = rpcUrl;\n this.clientId = clientId || getDefaultClientId();\n }\n\n async getInfos(appIDs: Address[], addressCount = 1): Promise<AppInfo[]> {\n const count = Math.min(addressCount, MAX_ADDRESS_COUNT);\n\n const endpoint = `${this.config.userApiServerURL}/info`;\n const url = `${endpoint}?${new URLSearchParams({ apps: appIDs.join(\",\") })}`;\n\n const res = await this.makeAuthenticatedRequest(url, CanViewSensitiveAppInfoPermission);\n const result: AppInfoResponse = await res.json();\n\n // optional: verify signatures with KMS key\n // const { signingKey } = getKMSKeysForEnvironment(this.config.name);\n\n // Truncate without mutating the original object\n // API returns apps in the same order as the request, so use appIDs[i] as the address\n return result.apps.map((app, i) => {\n // TODO: Implement signature verification\n // const valid = await verifyKMSSignature(appInfo.addresses, signingKey);\n // if (!valid) {\n // throw new Error(`Invalid signature for app ${appIDs[i]}`);\n // }\n\n // Slice derived addresses to requested count\n const evmAddresses = app.addresses?.data?.evmAddresses?.slice(0, count) || [];\n const solanaAddresses = app.addresses?.data?.solanaAddresses?.slice(0, count) || [];\n\n return {\n address: appIDs[i] as Address,\n status: app.app_status,\n ip: app.ip,\n machineType: app.machine_type,\n profile: app.profile,\n metrics: app.metrics,\n evmAddresses,\n solanaAddresses,\n };\n });\n }\n\n /**\n * Get 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 async uploadAppProfile(\n appAddress: Address,\n name: string,\n website?: string,\n description?: string,\n xURL?: string,\n imagePath?: string,\n ): Promise<{\n name: string;\n website?: string;\n description?: string;\n xURL?: string;\n imageURL?: string;\n }> {\n const endpoint = `${this.config.userApiServerURL}/apps/${appAddress}/profile`;\n\n // Build multipart form data using form-data package\n const formData = new FormData();\n\n // Add required name field\n formData.append(\"name\", name);\n\n // Add optional text fields\n if (website) {\n formData.append(\"website\", website);\n }\n if (description) {\n formData.append(\"description\", description);\n }\n if (xURL) {\n formData.append(\"xURL\", xURL);\n }\n\n // Add optional image file\n if (imagePath) {\n const fs = await import(\"fs\");\n const path = await import(\"path\");\n const fileName = path.basename(imagePath);\n\n // Read file into buffer\n const fileBuffer = fs.readFileSync(imagePath);\n formData.append(\"image\", fileBuffer, fileName);\n }\n\n // Make authenticated POST request\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n ...formData.getHeaders(),\n };\n\n // Add auth headers (Authorization and X-eigenx-expiry)\n if (this.account) {\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60); // 5 minutes\n const authHeaders = await this.generateAuthHeaders(CanUpdateAppProfilePermission, expiry);\n Object.assign(headers, authHeaders);\n }\n\n try {\n // Use axios to post req\n const response: AxiosResponse = await axios.post(endpoint, formData, {\n headers,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n maxContentLength: Infinity, // Allow large file uploads\n maxBodyLength: Infinity, // Allow large file uploads\n });\n\n const status = response.status;\n\n if (status !== 200 && status !== 201) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n\n // Detect Cloudflare challenge page\n if (status === 403 && body.includes(\"Cloudflare\") && body.includes(\"challenge-platform\")) {\n throw new Error(\n `Cloudflare protection is blocking the request. This is likely due to bot detection.\\n` +\n `Status: ${status}`,\n );\n }\n\n throw new Error(\n `UserAPI request failed: ${status} ${status >= 200 && status < 300 ? \"OK\" : \"Error\"} - ${body.substring(0, 500)}${body.length > 500 ? \"...\" : \"\"}`,\n );\n }\n\n return response.data;\n } catch (error: any) {\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to UserAPI at ${endpoint}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.userApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n throw error;\n }\n }\n\n private async makeAuthenticatedRequest(\n url: string,\n permission?: Hex,\n ): Promise<{ json: () => Promise<any>; text: () => Promise<string> }> {\n const headers: Record<string, string> = {\n \"x-client-id\": this.clientId,\n };\n // Add auth headers if permission is specified\n if (permission && this.account) {\n const expiry = BigInt(Math.floor(Date.now() / 1000) + 5 * 60); // 5 minutes\n const authHeaders = await this.generateAuthHeaders(permission, expiry);\n Object.assign(headers, authHeaders);\n }\n\n try {\n // Use axios to match\n const response: AxiosResponse = await axios.get(url, {\n headers,\n maxRedirects: 0,\n validateStatus: () => true, // Don't throw on any status\n });\n\n const status = response.status;\n const statusText = status >= 200 && status < 300 ? \"OK\" : \"Error\";\n\n if (status < 200 || status >= 300) {\n const body =\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data);\n throw new Error(`UserAPI request failed: ${status} ${statusText} - ${body}`);\n }\n\n // Return Response-like object for compatibility\n return {\n json: async () => response.data,\n text: async () =>\n typeof response.data === \"string\" ? response.data : JSON.stringify(response.data),\n };\n } catch (error: any) {\n // Handle network errors (fetch failed, connection refused, etc.)\n if (\n error.message?.includes(\"fetch failed\") ||\n error.message?.includes(\"ECONNREFUSED\") ||\n error.message?.includes(\"ENOTFOUND\") ||\n error.cause\n ) {\n const cause = error.cause?.message || error.cause || error.message;\n throw new Error(\n `Failed to connect to UserAPI at ${url}: ${cause}\\n` +\n `Please check:\\n` +\n `1. Your internet connection\\n` +\n `2. The API server is accessible: ${this.config.userApiServerURL}\\n` +\n `3. Firewall/proxy settings`,\n );\n }\n // Re-throw other errors as-is\n throw error;\n }\n }\n\n /**\n * Generate authentication headers for UserAPI requests\n */\n private async generateAuthHeaders(\n permission: Hex,\n expiry: bigint,\n ): Promise<Record<string, string>> {\n if (!this.account) {\n throw new Error(\"Private key required for authenticated requests\");\n }\n\n if (!this.rpcUrl) {\n throw new Error(\"RPC URL required for authenticated requests\");\n }\n\n const chain = getChainFromID(this.config.chainID);\n\n const publicClient = createPublicClient({\n chain,\n transport: http(this.rpcUrl),\n });\n\n // Calculate permission signature using shared auth utility\n const { signature } = await calculatePermissionSignature({\n permission,\n expiry,\n appControllerAddress: this.config.appControllerAddress,\n publicClient,\n account: this.account,\n });\n\n // Return auth headers\n return {\n Authorization: `Bearer ${stripHexPrefix(signature)}`,\n \"X-eigenx-expiry\": expiry.toString(),\n };\n }\n}\n\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 } from \"viem\";\nimport { privateKeyToAccount } from \"viem/accounts\";\nimport { createPublicClient } from \"viem\";\n\n// Minimal AppController ABI for permission calculation\nconst APP_CONTROLLER_ABI = parseAbi([\n \"function calculateApiPermissionDigestHash(bytes4 permission, uint256 expiry) view returns (bytes32)\",\n]);\n\nexport interface PermissionSignatureOptions {\n permission: Hex;\n expiry: bigint;\n appControllerAddress: Address;\n publicClient: ReturnType<typeof createPublicClient>;\n account: ReturnType<typeof privateKeyToAccount>;\n}\n\nexport interface PermissionSignatureResult {\n signature: string;\n digest: Hex;\n}\n\n/**\n * Calculate permission digest via AppController contract and sign it with EIP-191\n */\nexport async function calculatePermissionSignature(\n options: PermissionSignatureOptions,\n): Promise<PermissionSignatureResult> {\n const { permission, expiry, appControllerAddress, publicClient, account } = options;\n\n // Calculate permission digest hash using AppController contract\n const digest = (await publicClient.readContract({\n address: appControllerAddress,\n abi: APP_CONTROLLER_ABI,\n functionName: \"calculateApiPermissionDigestHash\",\n args: [permission, expiry],\n })) as Hex;\n\n // Sign the digest using EIP-191 (signMessage handles prefixing automatically)\n const signature = await account.signMessage({\n message: { raw: digest },\n });\n\n return { signature, digest };\n}\n\nexport interface BillingAuthSignatureOptions {\n account: ReturnType<typeof privateKeyToAccount>;\n product: string;\n expiry: bigint;\n}\n\nexport interface BillingAuthSignatureResult {\n signature: Hex;\n expiry: bigint;\n}\n\n/**\n * Sign billing authentication message using EIP-712 typed data\n */\nexport async function calculateBillingAuthSignature(\n options: BillingAuthSignatureOptions,\n): Promise<BillingAuthSignatureResult> {\n const { account, product, expiry } = options;\n\n // Sign using EIP-712 typed data\n const signature = await account.signTypedData({\n domain: {\n name: \"EigenCloud Billing API\",\n version: \"1\",\n },\n types: {\n BillingAuth: [\n { name: \"product\", type: \"string\" },\n { name: \"expiry\", type: \"uint256\" },\n ],\n },\n primaryType: \"BillingAuth\",\n message: {\n product,\n expiry,\n },\n });\n\n return { signature, expiry };\n}\n\nexport interface BuildAuthSignatureOptions {\n account: ReturnType<typeof privateKeyToAccount>;\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 { account, expiry } = options;\n\n const signature = await account.signTypedData({\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 * 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 * No-op telemetry client implementation\n */\n\nimport { TelemetryClient, Metric } from \"./types\";\n\n/**\n * NoopClient implements the TelemetryClient interface with no-op methods\n */\nexport class NoopClient implements TelemetryClient {\n /**\n * AddMetric implements the TelemetryClient interface\n */\n async addMetric(_metric: Metric): Promise<void> {\n // No-op\n }\n\n /**\n * Close implements the TelemetryClient interface\n */\n async close(): Promise<void> {\n // No-op\n }\n}\n\n/**\n * Check if a client is a NoopClient\n */\nexport function isNoopClient(client: TelemetryClient): boolean {\n return client instanceof NoopClient;\n}\n","/**\n * PostHog telemetry client implementation\n *\n * Uses the official posthog-node library\n */\n\nimport { PostHog } from \"posthog-node\";\nimport { TelemetryClient, Metric, AppEnvironment } from \"./types\";\n\n/**\n * PostHogClient implements the TelemetryClient interface using posthog-node\n */\nexport class PostHogClient implements TelemetryClient {\n private readonly client: PostHog;\n private readonly namespace: string;\n private readonly appEnvironment: AppEnvironment;\n\n constructor(environment: AppEnvironment, namespace: string, apiKey: string, endpoint?: string) {\n this.namespace = namespace;\n this.appEnvironment = environment;\n\n // Initialize PostHog client\n // posthog-node expects the full URL for the host option\n const host = endpoint || \"https://us.i.posthog.com\";\n\n this.client = new PostHog(apiKey, {\n host: host,\n flushAt: 1, // Flush immediately for CLI/SDK usage\n flushInterval: 0, // Disable interval flushing\n });\n\n // Identify the user with their UUID\n this.client.identify({\n distinctId: environment.userUUID,\n properties: {\n os: environment.os,\n arch: environment.arch,\n ...(environment.cliVersion ? { cliVersion: environment.cliVersion } : {}),\n },\n });\n }\n\n /**\n * AddMetric implements the TelemetryClient interface\n */\n async addMetric(metric: Metric): Promise<void> {\n // Never throw errors from telemetry operations\n try {\n // Create properties map starting with base properties\n const props: Record<string, any> = {\n name: metric.name,\n value: metric.value,\n };\n\n // Add metric dimensions\n for (const [k, v] of Object.entries(metric.dimensions)) {\n props[k] = v;\n }\n\n // Capture event using the namespace as the event name\n // With flushAt: 1, events are automatically flushed after each capture\n this.client.capture({\n distinctId: this.appEnvironment.userUUID,\n event: this.namespace,\n properties: props,\n });\n } catch {\n // Silently ignore telemetry errors\n }\n }\n\n /**\n * Close implements the TelemetryClient interface\n */\n async close(): Promise<void> {\n try {\n // Shutdown PostHog client and flush any pending events\n // shutdown() is synchronous but internally handles async cleanup\n this.client.shutdown();\n } catch {\n // Silently ignore errors during shutdown\n }\n }\n}\n\n/**\n * Embedded PostHog API key (can be exposed in TypeScript)\n * This can be set at build time or overridden via environment variable\n */\n// @ts-ignore - POSTHOG_API_KEY_BUILD_TIME is injected at build time by tsup\ndeclare const POSTHOG_API_KEY_BUILD_TIME: string | undefined;\n\n/**\n * Get PostHog API key from environment variable or build-time constant\n */\nexport function getPostHogAPIKey(): string | undefined {\n // Priority order:\n // 1. Environment variable\n // 2. Build-time constant (set at build time)\n // Check environment variable first\n if (process.env.ECLOUD_POSTHOG_KEY) {\n return process.env.ECLOUD_POSTHOG_KEY;\n }\n\n // Return build-time constant if available\n // @ts-ignore - POSTHOG_API_KEY_BUILD_TIME is injected at build time\n return typeof POSTHOG_API_KEY_BUILD_TIME !== \"undefined\" ? POSTHOG_API_KEY_BUILD_TIME : undefined;\n}\n\n/**\n * Get PostHog endpoint from environment variable or default\n */\nexport function getPostHogEndpoint(): string {\n return process.env.ECLOUD_POSTHOG_ENDPOINT || \"https://us.i.posthog.com\";\n}\n","/**\n * MetricsContext management\n */\n\nimport { MetricsContext } from \"./types\";\n\n/**\n * Create a new metrics context\n */\nexport function createMetricsContext(): MetricsContext {\n return {\n startTime: new Date(),\n metrics: [],\n properties: {},\n };\n}\n\n/**\n * Add a metric to the context without dimensions\n */\nexport function addMetric(context: MetricsContext, name: string, value: number): void {\n addMetricWithDimensions(context, name, value, {});\n}\n\n/**\n * Add a metric to the context with dimensions\n */\nexport function addMetricWithDimensions(\n context: MetricsContext,\n name: string,\n value: number,\n dimensions: Record<string, string>,\n): void {\n context.metrics.push({\n name,\n value,\n dimensions,\n });\n}\n","/**\n * Telemetry module for ECloud SDK and CLI\n *\n * Provides telemetry functionality matching the Go implementation.\n * Supports both \"ecloud-cli\" and \"ecloud-sdk\" namespaces.\n */\n\nimport { TelemetryClient, Metric, AppEnvironment } from \"./types\";\nimport { NoopClient, isNoopClient } from \"./noop\";\nimport { PostHogClient, getPostHogAPIKey, getPostHogEndpoint } from \"./posthog\";\nimport * as os from \"os\";\n\nexport * from \"./types\";\nexport * from \"./metricsContext\";\nexport * from \"./noop\";\nexport * from \"./posthog\";\nexport * from \"./wrapper\";\n\n/**\n * Options for creating a telemetry client\n */\nexport interface TelemetryClientOptions {\n /**\n * Whether telemetry is enabled (only enabled if explicitly set to true, defaults to disabled)\n */\n telemetryEnabled?: boolean;\n /**\n * PostHog API key (if not provided, will check environment variables)\n */\n apiKey?: string;\n /**\n * PostHog endpoint (if not provided, will use default)\n */\n endpoint?: string;\n}\n\n/**\n * Create a telemetry client\n *\n * @param environment - Application environment information (must include userUUID)\n * @param namespace - Namespace for telemetry events (\"ecloud-cli\" or \"ecloud-sdk\")\n * @param options - Optional telemetry client options\n * @returns TelemetryClient instance (NoopClient if telemetry is disabled or no API key)\n */\nexport function createTelemetryClient(\n environment: AppEnvironment,\n namespace: \"ecloud-cli\" | \"ecloud-sdk\",\n options?: TelemetryClientOptions,\n): TelemetryClient {\n // Check if telemetry is enabled\n // Only enabled if explicitly set to true\n // If undefined or false, telemetry is disabled\n const telemetryEnabled = options?.telemetryEnabled === true;\n\n // If telemetry is disabled, return noop client\n if (!telemetryEnabled) {\n return new NoopClient();\n }\n\n // Get API key from options, environment variable, or return noop\n const resolvedApiKey = options?.apiKey || getPostHogAPIKey();\n if (!resolvedApiKey) {\n // No API key available, return noop client\n return new NoopClient();\n }\n\n // Get endpoint from options or environment variable\n const endpoint = options?.endpoint || getPostHogEndpoint();\n\n try {\n return new PostHogClient(environment, namespace, resolvedApiKey, endpoint);\n } catch {\n // If initialization fails, return noop client\n return new NoopClient();\n }\n}\n\n/**\n * Create an AppEnvironment from current system information\n *\n * @param userUUID - User UUID for identification (required - no I/O in SDK)\n * @param cliVersion - Optional CLI version (for CLI usage)\n * @param osOverride - Optional OS override (defaults to current platform)\n * @param archOverride - Optional architecture override (defaults to current architecture)\n * @returns AppEnvironment with user UUID, OS, and architecture\n */\nexport function createAppEnvironment(\n userUUID: string,\n cliVersion?: string,\n osOverride?: string,\n archOverride?: string,\n): AppEnvironment {\n return {\n userUUID,\n cliVersion,\n os: osOverride || os.platform(),\n arch: archOverride || os.arch(),\n };\n}\n\n/**\n * Emit metrics from a metrics context\n *\n * @param client - Telemetry client to use\n * @param context - Metrics context containing metrics to emit\n * @returns Promise that resolves when all metrics are emitted\n */\nexport async function emitMetrics(\n client: TelemetryClient,\n context: {\n metrics: Metric[];\n properties: Record<string, string>;\n },\n): Promise<void> {\n if (isNoopClient(client)) {\n return;\n }\n\n // Emit each metric with properties merged into dimensions\n for (const metric of context.metrics) {\n const dimensions = {\n ...metric.dimensions,\n ...context.properties,\n };\n\n const metricWithProperties: Metric = {\n ...metric,\n dimensions,\n };\n\n try {\n await client.addMetric(metricWithProperties);\n } catch {\n // Silently ignore telemetry errors\n }\n }\n}\n","/**\n * Telemetry wrapper utilities for SDK functions\n *\n * Provides helpers to wrap SDK function execution with telemetry tracking\n */\n\nimport {\n createTelemetryClient,\n createAppEnvironment,\n createMetricsContext,\n addMetric,\n addMetricWithDimensions,\n emitMetrics,\n} from \"./index\";\nimport { randomUUID } from \"crypto\";\n\n/**\n * Generate a random UUID for telemetry identification\n * Used when userUUID is not provided (SDK usage outside CLI)\n */\nfunction generateRandomUUID(): string {\n return randomUUID();\n}\n\n/**\n * Options for telemetry wrapper\n */\nexport interface TelemetryWrapperOptions {\n /**\n * Function name for telemetry (e.g., \"deploy\", \"upgrade\", \"createApp\")\n */\n functionName: string;\n /**\n * Skip telemetry if true (used when called from CLI)\n */\n skipTelemetry?: boolean;\n /**\n * Additional properties to include in telemetry\n */\n properties?: Record<string, string>;\n /**\n * User UUID for identification (required if skipTelemetry is false)\n * If not provided and telemetry is enabled, will generate a random UUID for this session\n */\n userUUID?: string;\n /**\n * Whether telemetry is enabled (defaults to true if not provided)\n */\n telemetryEnabled?: boolean;\n /**\n * PostHog API key (optional, will check environment variables if not provided)\n */\n apiKey?: string;\n /**\n * PostHog endpoint (optional, will use default if not provided)\n */\n endpoint?: string;\n}\n\n/**\n * Wrap a function execution with telemetry\n *\n * @param options - Telemetry wrapper options\n * @param action - The function to execute\n * @returns The result of the action\n */\nexport async function withSDKTelemetry<T>(\n options: TelemetryWrapperOptions,\n action: () => Promise<T>,\n): Promise<T> {\n // Skip telemetry if requested (e.g., when called from CLI)\n if (options.skipTelemetry) {\n return action();\n }\n\n // Generate a random UUID if not provided (for SDK usage outside CLI)\n // This ensures each SDK session has a unique identifier\n const userUUID = options.userUUID || generateRandomUUID();\n\n const environment = createAppEnvironment(userUUID);\n const client = createTelemetryClient(environment, \"ecloud-sdk\", {\n telemetryEnabled: options.telemetryEnabled,\n apiKey: options.apiKey,\n endpoint: options.endpoint,\n });\n const metrics = createMetricsContext();\n\n // Set source to identify SDK usage\n metrics.properties[\"source\"] = \"ecloud-sdk\";\n\n // Set function name in properties\n metrics.properties[\"function\"] = options.functionName;\n\n // Add any additional properties\n if (options.properties) {\n Object.assign(metrics.properties, options.properties);\n }\n\n // Add initial count metric\n addMetric(metrics, \"Count\", 1);\n\n let actionError: Error | undefined;\n let result: T;\n\n try {\n result = await action();\n return result;\n } catch (err) {\n actionError = err instanceof Error ? err : new Error(String(err));\n throw err;\n } finally {\n // Add result metric\n const resultValue = actionError ? \"Failure\" : \"Success\";\n const dimensions: Record<string, string> = {};\n if (actionError) {\n dimensions[\"error\"] = actionError.message;\n }\n addMetricWithDimensions(metrics, resultValue, 1, dimensions);\n\n // Add duration metric\n const duration = Date.now() - metrics.startTime.getTime();\n addMetric(metrics, \"DurationMilliseconds\", duration);\n\n // Emit all metrics\n try {\n await emitMetrics(client, metrics);\n await client.close();\n } catch {\n // Silently ignore telemetry errors\n }\n }\n}\n","/**\n * Default logger\n */\n\nimport { Logger } from \"../types\";\n\nexport const defaultLogger: Logger = {\n info: (...args) => console.info(...args),\n warn: (...args) => console.warn(...args),\n error: (...args) => console.error(...args),\n debug: (...args) => console.debug(...args),\n};\n\nexport const getLogger: (verbose?: boolean) => Logger = (verbose?: boolean) => ({\n info: (...args) => console.info(...args),\n warn: (...args) => console.warn(...args),\n error: (...args) => console.error(...args),\n debug: (...args) => verbose && console.debug(...args),\n});\n","/**\n * ESM and CJS compatible getDirname utility\n */\n\nimport * as path from \"path\";\nimport { fileURLToPath } from \"url\";\n\n/**\n * Get __dirname equivalent that works in both ESM and CJS\n * In CJS builds, __dirname is available and will be used\n * In ESM builds, import.meta.url is used\n */\nexport function getDirname(): string {\n // Check for CJS __dirname first (available in CommonJS)\n if (typeof __dirname !== \"undefined\") {\n return __dirname;\n }\n\n // For ESM, we need to use import.meta.url\n // This will be evaluated at build time by tsup for ESM builds\n // For CJS builds, the above check will catch it, so this won't execute\n try {\n const metaUrl = import.meta.url;\n return path.dirname(fileURLToPath(metaUrl));\n } catch {\n // Fallback (shouldn't reach here in normal usage)\n return process.cwd();\n }\n}\n"],"mappings":"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","names":["sepolia","sepolia","path"]}
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
getLogger,
|
|
7
7
|
isSubscriptionActive,
|
|
8
8
|
withSDKTelemetry
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-FY7UU55U.js";
|
|
10
10
|
|
|
11
11
|
// src/client/common/auth/keyring.ts
|
|
12
12
|
import { AsyncEntry, findCredentials } from "@napi-rs/keyring";
|
|
@@ -431,4 +431,4 @@ export {
|
|
|
431
431
|
generateNewPrivateKey,
|
|
432
432
|
createBillingModule
|
|
433
433
|
};
|
|
434
|
-
//# sourceMappingURL=chunk-
|
|
434
|
+
//# sourceMappingURL=chunk-GB4GM4C2.js.map
|
|
@@ -17,17 +17,10 @@ import {
|
|
|
17
17
|
getLogger,
|
|
18
18
|
stripHexPrefix,
|
|
19
19
|
withSDKTelemetry
|
|
20
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-FY7UU55U.js";
|
|
21
21
|
|
|
22
22
|
// src/client/common/contract/eip7702.ts
|
|
23
|
-
import {
|
|
24
|
-
encodeFunctionData as encodeFunctionData2,
|
|
25
|
-
encodeAbiParameters,
|
|
26
|
-
decodeErrorResult as decodeErrorResult2,
|
|
27
|
-
keccak256,
|
|
28
|
-
toBytes,
|
|
29
|
-
concat
|
|
30
|
-
} from "viem";
|
|
23
|
+
import { encodeFunctionData as encodeFunctionData2, encodeAbiParameters, decodeErrorResult as decodeErrorResult2 } from "viem";
|
|
31
24
|
|
|
32
25
|
// src/client/common/abis/ERC7702Delegator.json
|
|
33
26
|
var ERC7702Delegator_default = [
|
|
@@ -3214,27 +3207,55 @@ async function undelegate(options, logger) {
|
|
|
3214
3207
|
}
|
|
3215
3208
|
|
|
3216
3209
|
// src/client/common/contract/eip7702.ts
|
|
3210
|
+
var EXECUTE_BATCH_MODE = "0x0100000000000000000000000000000000000000000000000000000000000000";
|
|
3211
|
+
var GAS_LIMIT_BUFFER_PERCENTAGE = 20n;
|
|
3212
|
+
var GAS_PRICE_BUFFER_PERCENTAGE = 100n;
|
|
3213
|
+
function encodeExecuteBatchData(executions) {
|
|
3214
|
+
const encodedExecutions = encodeAbiParameters(
|
|
3215
|
+
[
|
|
3216
|
+
{
|
|
3217
|
+
type: "tuple[]",
|
|
3218
|
+
components: [
|
|
3219
|
+
{ name: "target", type: "address" },
|
|
3220
|
+
{ name: "value", type: "uint256" },
|
|
3221
|
+
{ name: "callData", type: "bytes" }
|
|
3222
|
+
]
|
|
3223
|
+
}
|
|
3224
|
+
],
|
|
3225
|
+
[executions]
|
|
3226
|
+
);
|
|
3227
|
+
return encodeFunctionData2({
|
|
3228
|
+
abi: ERC7702Delegator_default,
|
|
3229
|
+
functionName: "execute",
|
|
3230
|
+
args: [EXECUTE_BATCH_MODE, encodedExecutions]
|
|
3231
|
+
});
|
|
3232
|
+
}
|
|
3217
3233
|
async function estimateBatchGas(options) {
|
|
3218
|
-
const { publicClient, executions } = options;
|
|
3219
|
-
const
|
|
3220
|
-
const
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3234
|
+
const { publicClient, account, executions } = options;
|
|
3235
|
+
const executeBatchData = encodeExecuteBatchData(executions);
|
|
3236
|
+
const [gasTipCap, block, estimatedGas] = await Promise.all([
|
|
3237
|
+
publicClient.estimateMaxPriorityFeePerGas(),
|
|
3238
|
+
publicClient.getBlock(),
|
|
3239
|
+
publicClient.estimateGas({
|
|
3240
|
+
account,
|
|
3241
|
+
to: account,
|
|
3242
|
+
data: executeBatchData
|
|
3243
|
+
})
|
|
3244
|
+
]);
|
|
3245
|
+
const baseFee = block.baseFeePerGas ?? 0n;
|
|
3246
|
+
const maxFeePerGas = (baseFee + gasTipCap) * (100n + GAS_PRICE_BUFFER_PERCENTAGE) / 100n;
|
|
3247
|
+
const gasLimit = estimatedGas * (100n + GAS_LIMIT_BUFFER_PERCENTAGE) / 100n;
|
|
3226
3248
|
const maxCostWei = gasLimit * maxFeePerGas;
|
|
3227
|
-
const maxCostEth = formatETH(maxCostWei);
|
|
3228
3249
|
return {
|
|
3229
3250
|
gasLimit,
|
|
3230
3251
|
maxFeePerGas,
|
|
3231
|
-
maxPriorityFeePerGas,
|
|
3252
|
+
maxPriorityFeePerGas: gasTipCap,
|
|
3232
3253
|
maxCostWei,
|
|
3233
|
-
maxCostEth
|
|
3254
|
+
maxCostEth: formatETH(maxCostWei)
|
|
3234
3255
|
};
|
|
3235
3256
|
}
|
|
3236
3257
|
async function checkERC7702Delegation(publicClient, account, delegatorAddress) {
|
|
3237
|
-
const code = await publicClient.
|
|
3258
|
+
const code = await publicClient.getCode({ address: account });
|
|
3238
3259
|
if (!code) {
|
|
3239
3260
|
return false;
|
|
3240
3261
|
}
|
|
@@ -3251,36 +3272,7 @@ async function executeBatch(options, logger) {
|
|
|
3251
3272
|
if (!chain) {
|
|
3252
3273
|
throw new Error("Wallet client must have a chain");
|
|
3253
3274
|
}
|
|
3254
|
-
const
|
|
3255
|
-
[
|
|
3256
|
-
{
|
|
3257
|
-
type: "tuple[]",
|
|
3258
|
-
components: [
|
|
3259
|
-
{ name: "target", type: "address" },
|
|
3260
|
-
{ name: "value", type: "uint256" },
|
|
3261
|
-
{ name: "callData", type: "bytes" }
|
|
3262
|
-
]
|
|
3263
|
-
}
|
|
3264
|
-
],
|
|
3265
|
-
[executions]
|
|
3266
|
-
);
|
|
3267
|
-
const executeBatchMode = "0x0100000000000000000000000000000000000000000000000000000000000000";
|
|
3268
|
-
let executeBatchData;
|
|
3269
|
-
try {
|
|
3270
|
-
executeBatchData = encodeFunctionData2({
|
|
3271
|
-
abi: ERC7702Delegator_default,
|
|
3272
|
-
functionName: "execute",
|
|
3273
|
-
args: [executeBatchMode, encodedExecutions]
|
|
3274
|
-
});
|
|
3275
|
-
} catch {
|
|
3276
|
-
const functionSignature = "execute(bytes32,bytes)";
|
|
3277
|
-
const selector = keccak256(toBytes(functionSignature)).slice(0, 10);
|
|
3278
|
-
const encodedParams = encodeAbiParameters(
|
|
3279
|
-
[{ type: "bytes32" }, { type: "bytes" }],
|
|
3280
|
-
[executeBatchMode, encodedExecutions]
|
|
3281
|
-
);
|
|
3282
|
-
executeBatchData = concat([selector, encodedParams]);
|
|
3283
|
-
}
|
|
3275
|
+
const executeBatchData = encodeExecuteBatchData(executions);
|
|
3284
3276
|
const isDelegated2 = await checkERC7702Delegation(
|
|
3285
3277
|
publicClient,
|
|
3286
3278
|
account.address,
|
|
@@ -3829,9 +3821,9 @@ async function pushDockerImage(docker, imageRef, logger) {
|
|
|
3829
3821
|
if (!output.includes("digest:") && !output.includes("pushed") && !output.includes("Pushed")) {
|
|
3830
3822
|
logger?.debug?.("No clear success indicator in push output, verifying...");
|
|
3831
3823
|
}
|
|
3832
|
-
logger?.info?.("Image push completed successfully");
|
|
3833
3824
|
try {
|
|
3834
3825
|
await verifyImageExists(imageRef, logger);
|
|
3826
|
+
logger?.info?.("Image push completed successfully");
|
|
3835
3827
|
resolve2();
|
|
3836
3828
|
} catch (error) {
|
|
3837
3829
|
reject(error);
|
|
@@ -4654,6 +4646,67 @@ Please verify the image exists: docker manifest inspect ${finalImageRef}`
|
|
|
4654
4646
|
};
|
|
4655
4647
|
}
|
|
4656
4648
|
|
|
4649
|
+
// src/client/common/release/prebuilt.ts
|
|
4650
|
+
async function createReleaseFromImageDigest(options, logger) {
|
|
4651
|
+
const { imageRef, imageDigest, envFilePath, instanceType, environmentConfig, appId } = options;
|
|
4652
|
+
if (!/^sha256:[0-9a-f]{64}$/i.test(imageDigest)) {
|
|
4653
|
+
throw new Error(`imageDigest must be in format sha256:<64 hex>, got: ${imageDigest}`);
|
|
4654
|
+
}
|
|
4655
|
+
let publicEnv = {};
|
|
4656
|
+
let privateEnv = {};
|
|
4657
|
+
if (envFilePath) {
|
|
4658
|
+
logger.info("Parsing environment file...");
|
|
4659
|
+
const parsed = parseAndValidateEnvFile(envFilePath);
|
|
4660
|
+
publicEnv = parsed.public;
|
|
4661
|
+
privateEnv = parsed.private;
|
|
4662
|
+
} else {
|
|
4663
|
+
logger.info("Continuing without environment file");
|
|
4664
|
+
}
|
|
4665
|
+
publicEnv["EIGEN_MACHINE_TYPE_PUBLIC"] = instanceType;
|
|
4666
|
+
logger.info(`Instance type: ${instanceType}`);
|
|
4667
|
+
logger.info("Encrypting environment variables...");
|
|
4668
|
+
const { encryptionKey } = getKMSKeysForEnvironment(
|
|
4669
|
+
environmentConfig.name,
|
|
4670
|
+
environmentConfig.build
|
|
4671
|
+
);
|
|
4672
|
+
const protectedHeaders = getAppProtectedHeaders(appId);
|
|
4673
|
+
const privateEnvBytes = Buffer.from(JSON.stringify(privateEnv));
|
|
4674
|
+
const encryptedEnvStr = await encryptRSAOAEPAndAES256GCM(
|
|
4675
|
+
encryptionKey,
|
|
4676
|
+
privateEnvBytes,
|
|
4677
|
+
protectedHeaders
|
|
4678
|
+
);
|
|
4679
|
+
const digestHex = imageDigest.split(":")[1];
|
|
4680
|
+
const digestBytes = new Uint8Array(Buffer.from(digestHex, "hex"));
|
|
4681
|
+
if (digestBytes.length !== 32) {
|
|
4682
|
+
throw new Error(`Digest must be exactly 32 bytes, got ${digestBytes.length}`);
|
|
4683
|
+
}
|
|
4684
|
+
const registry = extractRegistryNameNoDocker(imageRef);
|
|
4685
|
+
return {
|
|
4686
|
+
rmsRelease: {
|
|
4687
|
+
artifacts: [{ digest: digestBytes, registry }],
|
|
4688
|
+
upgradeByTime: Math.floor(Date.now() / 1e3) + 3600
|
|
4689
|
+
},
|
|
4690
|
+
publicEnv: new Uint8Array(Buffer.from(JSON.stringify(publicEnv))),
|
|
4691
|
+
encryptedEnv: new Uint8Array(Buffer.from(encryptedEnvStr))
|
|
4692
|
+
};
|
|
4693
|
+
}
|
|
4694
|
+
function extractRegistryNameNoDocker(imageRef) {
|
|
4695
|
+
let name = imageRef;
|
|
4696
|
+
const tagIndex = name.lastIndexOf(":");
|
|
4697
|
+
if (tagIndex !== -1 && !name.substring(tagIndex + 1).includes("/")) {
|
|
4698
|
+
name = name.substring(0, tagIndex);
|
|
4699
|
+
}
|
|
4700
|
+
const digestIndex = name.indexOf("@");
|
|
4701
|
+
if (digestIndex !== -1) {
|
|
4702
|
+
name = name.substring(0, digestIndex);
|
|
4703
|
+
}
|
|
4704
|
+
if ([...name].filter((c) => c === "/").length === 1) {
|
|
4705
|
+
name = `docker.io/${name}`;
|
|
4706
|
+
}
|
|
4707
|
+
return name;
|
|
4708
|
+
}
|
|
4709
|
+
|
|
4657
4710
|
// src/client/common/contract/watcher.ts
|
|
4658
4711
|
var WATCH_POLL_INTERVAL_SECONDS = 5;
|
|
4659
4712
|
var APP_STATUS_RUNNING = "Running";
|
|
@@ -4835,6 +4888,97 @@ function validatePrivateKey(key) {
|
|
|
4835
4888
|
}
|
|
4836
4889
|
|
|
4837
4890
|
// src/client/modules/compute/app/deploy.ts
|
|
4891
|
+
async function prepareDeployFromVerifiableBuild(options, logger = defaultLogger) {
|
|
4892
|
+
return withSDKTelemetry(
|
|
4893
|
+
{
|
|
4894
|
+
functionName: "prepareDeployFromVerifiableBuild",
|
|
4895
|
+
skipTelemetry: options.skipTelemetry,
|
|
4896
|
+
properties: {
|
|
4897
|
+
environment: options.environment || "sepolia"
|
|
4898
|
+
}
|
|
4899
|
+
},
|
|
4900
|
+
async () => {
|
|
4901
|
+
if (!options.privateKey) throw new Error("privateKey is required for deployment");
|
|
4902
|
+
if (!options.imageRef) throw new Error("imageRef is required for deployment");
|
|
4903
|
+
if (!options.imageDigest) throw new Error("imageDigest is required for deployment");
|
|
4904
|
+
assertValidImageReference(options.imageRef);
|
|
4905
|
+
validateAppName(options.appName);
|
|
4906
|
+
validateLogVisibility(options.logVisibility);
|
|
4907
|
+
if (!/^sha256:[0-9a-f]{64}$/i.test(options.imageDigest)) {
|
|
4908
|
+
throw new Error(
|
|
4909
|
+
`imageDigest must be in format sha256:<64 hex>, got: ${options.imageDigest}`
|
|
4910
|
+
);
|
|
4911
|
+
}
|
|
4912
|
+
const { publicLogs } = validateLogVisibility(options.logVisibility);
|
|
4913
|
+
validateResourceUsageMonitoring(options.resourceUsageMonitoring);
|
|
4914
|
+
logger.debug("Performing preflight checks...");
|
|
4915
|
+
const preflightCtx = await doPreflightChecks(
|
|
4916
|
+
{
|
|
4917
|
+
privateKey: options.privateKey,
|
|
4918
|
+
rpcUrl: options.rpcUrl,
|
|
4919
|
+
environment: options.environment
|
|
4920
|
+
},
|
|
4921
|
+
logger
|
|
4922
|
+
);
|
|
4923
|
+
logger.debug("Checking quota availability...");
|
|
4924
|
+
await checkQuotaAvailable(preflightCtx);
|
|
4925
|
+
const salt = generateRandomSalt();
|
|
4926
|
+
logger.debug(`Generated salt: ${Buffer.from(salt).toString("hex")}`);
|
|
4927
|
+
logger.debug("Calculating app ID...");
|
|
4928
|
+
const appIDToBeDeployed = await calculateAppID(
|
|
4929
|
+
preflightCtx.privateKey,
|
|
4930
|
+
options.rpcUrl || preflightCtx.rpcUrl,
|
|
4931
|
+
preflightCtx.environmentConfig,
|
|
4932
|
+
salt
|
|
4933
|
+
);
|
|
4934
|
+
logger.info(``);
|
|
4935
|
+
logger.info(`App ID: ${appIDToBeDeployed}`);
|
|
4936
|
+
logger.info(``);
|
|
4937
|
+
const release = await createReleaseFromImageDigest(
|
|
4938
|
+
{
|
|
4939
|
+
imageRef: options.imageRef,
|
|
4940
|
+
imageDigest: options.imageDigest,
|
|
4941
|
+
envFilePath: options.envFilePath,
|
|
4942
|
+
instanceType: options.instanceType,
|
|
4943
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
4944
|
+
appId: appIDToBeDeployed
|
|
4945
|
+
},
|
|
4946
|
+
logger
|
|
4947
|
+
);
|
|
4948
|
+
logger.debug("Preparing deploy batch...");
|
|
4949
|
+
const batch = await prepareDeployBatch(
|
|
4950
|
+
{
|
|
4951
|
+
privateKey: preflightCtx.privateKey,
|
|
4952
|
+
rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,
|
|
4953
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
4954
|
+
salt,
|
|
4955
|
+
release,
|
|
4956
|
+
publicLogs
|
|
4957
|
+
},
|
|
4958
|
+
logger
|
|
4959
|
+
);
|
|
4960
|
+
logger.debug("Estimating gas...");
|
|
4961
|
+
const gasEstimate = await estimateBatchGas({
|
|
4962
|
+
publicClient: batch.publicClient,
|
|
4963
|
+
account: batch.walletClient.account.address,
|
|
4964
|
+
executions: batch.executions
|
|
4965
|
+
});
|
|
4966
|
+
const data = {
|
|
4967
|
+
appId: batch.appId,
|
|
4968
|
+
salt: batch.salt,
|
|
4969
|
+
executions: batch.executions
|
|
4970
|
+
};
|
|
4971
|
+
return {
|
|
4972
|
+
prepared: {
|
|
4973
|
+
data,
|
|
4974
|
+
appName: options.appName,
|
|
4975
|
+
imageRef: options.imageRef
|
|
4976
|
+
},
|
|
4977
|
+
gasEstimate
|
|
4978
|
+
};
|
|
4979
|
+
}
|
|
4980
|
+
);
|
|
4981
|
+
}
|
|
4838
4982
|
function validateDeployOptions(options) {
|
|
4839
4983
|
if (!options.privateKey) {
|
|
4840
4984
|
throw new Error("privateKey is required for deployment");
|
|
@@ -5055,7 +5199,7 @@ async function prepareDeploy(options, logger = defaultLogger) {
|
|
|
5055
5199
|
logger.debug("Estimating gas...");
|
|
5056
5200
|
const gasEstimate = await estimateBatchGas({
|
|
5057
5201
|
publicClient: batch.publicClient,
|
|
5058
|
-
|
|
5202
|
+
account: batch.walletClient.account.address,
|
|
5059
5203
|
executions: batch.executions
|
|
5060
5204
|
});
|
|
5061
5205
|
const data = {
|
|
@@ -5145,6 +5289,81 @@ async function checkAppLogPermission(preflightCtx, appAddress, logger) {
|
|
|
5145
5289
|
}
|
|
5146
5290
|
|
|
5147
5291
|
// src/client/modules/compute/app/upgrade.ts
|
|
5292
|
+
async function prepareUpgradeFromVerifiableBuild(options, logger = defaultLogger) {
|
|
5293
|
+
return withSDKTelemetry(
|
|
5294
|
+
{
|
|
5295
|
+
functionName: "prepareUpgradeFromVerifiableBuild",
|
|
5296
|
+
skipTelemetry: options.skipTelemetry,
|
|
5297
|
+
properties: {
|
|
5298
|
+
environment: options.environment || "sepolia"
|
|
5299
|
+
}
|
|
5300
|
+
},
|
|
5301
|
+
async () => {
|
|
5302
|
+
logger.debug("Performing preflight checks...");
|
|
5303
|
+
const preflightCtx = await doPreflightChecks(
|
|
5304
|
+
{
|
|
5305
|
+
privateKey: options.privateKey,
|
|
5306
|
+
rpcUrl: options.rpcUrl,
|
|
5307
|
+
environment: options.environment
|
|
5308
|
+
},
|
|
5309
|
+
logger
|
|
5310
|
+
);
|
|
5311
|
+
const appID = validateUpgradeOptions(options);
|
|
5312
|
+
assertValidImageReference(options.imageRef);
|
|
5313
|
+
if (!/^sha256:[0-9a-f]{64}$/i.test(options.imageDigest)) {
|
|
5314
|
+
throw new Error(
|
|
5315
|
+
`imageDigest must be in format sha256:<64 hex>, got: ${options.imageDigest}`
|
|
5316
|
+
);
|
|
5317
|
+
}
|
|
5318
|
+
const { publicLogs } = validateLogVisibility(options.logVisibility);
|
|
5319
|
+
validateResourceUsageMonitoring(options.resourceUsageMonitoring);
|
|
5320
|
+
const envFilePath = options.envFilePath || "";
|
|
5321
|
+
logger.info("Preparing release (verifiable build, no local layering)...");
|
|
5322
|
+
const release = await createReleaseFromImageDigest(
|
|
5323
|
+
{
|
|
5324
|
+
imageRef: options.imageRef,
|
|
5325
|
+
imageDigest: options.imageDigest,
|
|
5326
|
+
envFilePath,
|
|
5327
|
+
instanceType: options.instanceType,
|
|
5328
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
5329
|
+
appId: appID
|
|
5330
|
+
},
|
|
5331
|
+
logger
|
|
5332
|
+
);
|
|
5333
|
+
logger.debug("Checking current log permission state...");
|
|
5334
|
+
const currentlyPublic = await checkAppLogPermission(preflightCtx, appID, logger);
|
|
5335
|
+
const needsPermissionChange = currentlyPublic !== publicLogs;
|
|
5336
|
+
logger.debug("Preparing upgrade batch...");
|
|
5337
|
+
const batch = await prepareUpgradeBatch({
|
|
5338
|
+
privateKey: preflightCtx.privateKey,
|
|
5339
|
+
rpcUrl: options.rpcUrl || preflightCtx.rpcUrl,
|
|
5340
|
+
environmentConfig: preflightCtx.environmentConfig,
|
|
5341
|
+
appId: appID,
|
|
5342
|
+
release,
|
|
5343
|
+
publicLogs,
|
|
5344
|
+
needsPermissionChange
|
|
5345
|
+
});
|
|
5346
|
+
logger.debug("Estimating gas...");
|
|
5347
|
+
const gasEstimate = await estimateBatchGas({
|
|
5348
|
+
publicClient: batch.publicClient,
|
|
5349
|
+
account: batch.walletClient.account.address,
|
|
5350
|
+
executions: batch.executions
|
|
5351
|
+
});
|
|
5352
|
+
const data = {
|
|
5353
|
+
appId: batch.appId,
|
|
5354
|
+
executions: batch.executions
|
|
5355
|
+
};
|
|
5356
|
+
return {
|
|
5357
|
+
prepared: {
|
|
5358
|
+
data,
|
|
5359
|
+
appId: appID,
|
|
5360
|
+
imageRef: options.imageRef
|
|
5361
|
+
},
|
|
5362
|
+
gasEstimate
|
|
5363
|
+
};
|
|
5364
|
+
}
|
|
5365
|
+
);
|
|
5366
|
+
}
|
|
5148
5367
|
function validateUpgradeOptions(options) {
|
|
5149
5368
|
if (!options.privateKey) {
|
|
5150
5369
|
throw new Error("privateKey is required for upgrade");
|
|
@@ -5307,7 +5526,7 @@ async function prepareUpgrade(options, logger = defaultLogger) {
|
|
|
5307
5526
|
logger.debug("Estimating gas...");
|
|
5308
5527
|
const gasEstimate = await estimateBatchGas({
|
|
5309
5528
|
publicClient: batch.publicClient,
|
|
5310
|
-
|
|
5529
|
+
account: batch.walletClient.account.address,
|
|
5311
5530
|
executions: batch.executions
|
|
5312
5531
|
});
|
|
5313
5532
|
const data = {
|
|
@@ -6135,6 +6354,24 @@ function createAppModule(ctx) {
|
|
|
6135
6354
|
logger
|
|
6136
6355
|
);
|
|
6137
6356
|
},
|
|
6357
|
+
async prepareDeployFromVerifiableBuild(opts) {
|
|
6358
|
+
return prepareDeployFromVerifiableBuild(
|
|
6359
|
+
{
|
|
6360
|
+
privateKey,
|
|
6361
|
+
rpcUrl: ctx.rpcUrl,
|
|
6362
|
+
environment: ctx.environment,
|
|
6363
|
+
appName: opts.name,
|
|
6364
|
+
instanceType: opts.instanceType,
|
|
6365
|
+
envFilePath: opts.envFile,
|
|
6366
|
+
imageRef: opts.imageRef,
|
|
6367
|
+
imageDigest: opts.imageDigest,
|
|
6368
|
+
logVisibility: opts.logVisibility,
|
|
6369
|
+
resourceUsageMonitoring: opts.resourceUsageMonitoring,
|
|
6370
|
+
skipTelemetry
|
|
6371
|
+
},
|
|
6372
|
+
logger
|
|
6373
|
+
);
|
|
6374
|
+
},
|
|
6138
6375
|
async executeDeploy(prepared, gas) {
|
|
6139
6376
|
const account = privateKeyToAccount3(privateKey);
|
|
6140
6377
|
const chain = getChainFromID(environment.chainID);
|
|
@@ -6195,6 +6432,24 @@ function createAppModule(ctx) {
|
|
|
6195
6432
|
logger
|
|
6196
6433
|
);
|
|
6197
6434
|
},
|
|
6435
|
+
async prepareUpgradeFromVerifiableBuild(appId, opts) {
|
|
6436
|
+
return prepareUpgradeFromVerifiableBuild(
|
|
6437
|
+
{
|
|
6438
|
+
appId,
|
|
6439
|
+
privateKey,
|
|
6440
|
+
rpcUrl: ctx.rpcUrl,
|
|
6441
|
+
environment: ctx.environment,
|
|
6442
|
+
instanceType: opts.instanceType,
|
|
6443
|
+
envFilePath: opts.envFile,
|
|
6444
|
+
imageRef: opts.imageRef,
|
|
6445
|
+
imageDigest: opts.imageDigest,
|
|
6446
|
+
logVisibility: opts.logVisibility,
|
|
6447
|
+
resourceUsageMonitoring: opts.resourceUsageMonitoring,
|
|
6448
|
+
skipTelemetry
|
|
6449
|
+
},
|
|
6450
|
+
logger
|
|
6451
|
+
);
|
|
6452
|
+
},
|
|
6198
6453
|
async executeUpgrade(prepared, gas) {
|
|
6199
6454
|
const account = privateKeyToAccount3(privateKey);
|
|
6200
6455
|
const chain = getChainFromID(environment.chainID);
|
|
@@ -6440,9 +6695,11 @@ export {
|
|
|
6440
6695
|
validateUpgradeParams,
|
|
6441
6696
|
validateCreateAppParams,
|
|
6442
6697
|
validateLogsParams,
|
|
6698
|
+
prepareDeployFromVerifiableBuild,
|
|
6443
6699
|
prepareDeploy,
|
|
6444
6700
|
executeDeploy,
|
|
6445
6701
|
watchDeployment,
|
|
6702
|
+
prepareUpgradeFromVerifiableBuild,
|
|
6446
6703
|
prepareUpgrade,
|
|
6447
6704
|
executeUpgrade,
|
|
6448
6705
|
watchUpgrade,
|
|
@@ -6459,4 +6716,4 @@ export {
|
|
|
6459
6716
|
createAppModule,
|
|
6460
6717
|
createComputeModule
|
|
6461
6718
|
};
|
|
6462
|
-
//# sourceMappingURL=chunk-
|
|
6719
|
+
//# sourceMappingURL=chunk-O7EU5JL7.js.map
|