diff --git a/packages/sdk/src/client/common/abis/AppController.json b/packages/sdk/src/client/common/abis/AppController.json index 4608a2ed..9f1f8645 100644 --- a/packages/sdk/src/client/common/abis/AppController.json +++ b/packages/sdk/src/client/common/abis/AppController.json @@ -10,27 +10,27 @@ { "name": "_permissionController", "type": "address", - "internalType": "contractIPermissionController" + "internalType": "contract IPermissionController" }, { "name": "_releaseManager", "type": "address", - "internalType": "contractIReleaseManager" + "internalType": "contract IReleaseManager" }, { "name": "_computeAVSRegistrar", "type": "address", - "internalType": "contractIComputeAVSRegistrar" + "internalType": "contract IComputeAVSRegistrar" }, { "name": "_computeOperator", "type": "address", - "internalType": "contractIComputeOperator" + "internalType": "contract IComputeOperator" }, { "name": "_appBeacon", "type": "address", - "internalType": "contractIBeacon" + "internalType": "contract IBeacon" } ], "stateMutability": "nonpayable" @@ -56,7 +56,7 @@ { "name": "", "type": "address", - "internalType": "contractIBeacon" + "internalType": "contract IBeacon" } ], "stateMutability": "view" @@ -104,7 +104,7 @@ { "name": "", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "stateMutability": "view" @@ -117,7 +117,7 @@ { "name": "", "type": "address", - "internalType": "contractIComputeAVSRegistrar" + "internalType": "contract IComputeAVSRegistrar" } ], "stateMutability": "view" @@ -130,11 +130,24 @@ { "name": "", "type": "address", - "internalType": "contractIComputeOperator" + "internalType": "contract IComputeOperator" } ], "stateMutability": "view" }, + { + "type": "function", + "name": "confirmUpgrade", + "inputs": [ + { + "name": "app", + "type": "address", + "internalType": "contract IApp" + } + ], + "outputs": [], + "stateMutability": "nonpayable" + }, { "type": "function", "name": "createApp", @@ -147,17 +160,17 @@ { "name": "release", "type": "tuple", - "internalType": "structIAppController.Release", + "internalType": "struct IAppController.Release", "components": [ { "name": "rmsRelease", "type": "tuple", - "internalType": "structIReleaseManagerTypes.Release", + "internalType": "struct IReleaseManagerTypes.Release", "components": [ { "name": "artifacts", "type": "tuple[]", - "internalType": "structIReleaseManagerTypes.Artifact[]", + "internalType": "struct IReleaseManagerTypes.Artifact[]", "components": [ { "name": "digest", @@ -187,6 +200,62 @@ "name": "encryptedEnv", "type": "bytes", "internalType": "bytes" + }, + { + "name": "containerPolicy", + "type": "tuple", + "internalType": "struct IAppController.ContainerPolicy", + "components": [ + { + "name": "args", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "cmdOverride", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "env", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "envOverride", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "restartPolicy", + "type": "string", + "internalType": "string" + } + ] } ] } @@ -195,7 +264,7 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "stateMutability": "nonpayable" @@ -212,17 +281,17 @@ { "name": "release", "type": "tuple", - "internalType": "structIAppController.Release", + "internalType": "struct IAppController.Release", "components": [ { "name": "rmsRelease", "type": "tuple", - "internalType": "structIReleaseManagerTypes.Release", + "internalType": "struct IReleaseManagerTypes.Release", "components": [ { "name": "artifacts", "type": "tuple[]", - "internalType": "structIReleaseManagerTypes.Artifact[]", + "internalType": "struct IReleaseManagerTypes.Artifact[]", "components": [ { "name": "digest", @@ -252,6 +321,62 @@ "name": "encryptedEnv", "type": "bytes", "internalType": "bytes" + }, + { + "name": "containerPolicy", + "type": "tuple", + "internalType": "struct IAppController.ContainerPolicy", + "components": [ + { + "name": "args", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "cmdOverride", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "env", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "envOverride", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "restartPolicy", + "type": "string", + "internalType": "string" + } + ] } ] } @@ -260,7 +385,45 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "createEmptyApp", + "inputs": [ + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "app", + "type": "address", + "internalType": "contract IApp" + } + ], + "stateMutability": "nonpayable" + }, + { + "type": "function", + "name": "createEmptyAppWithIsolatedBilling", + "inputs": [ + { + "name": "salt", + "type": "bytes32", + "internalType": "bytes32" + } + ], + "outputs": [ + { + "name": "app", + "type": "address", + "internalType": "contract IApp" } ], "stateMutability": "nonpayable" @@ -299,50 +462,50 @@ }, { "type": "function", - "name": "getBillingType", + "name": "getAppCreator", "inputs": [ { "name": "app", "type": "address", - "internalType": "address" + "internalType": "contract IApp" } ], "outputs": [ { "name": "", - "type": "uint8", - "internalType": "uint8" + "type": "address", + "internalType": "address" } ], "stateMutability": "view" }, { "type": "function", - "name": "getAppCreator", + "name": "getAppLatestReleaseBlockNumber", "inputs": [ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [ { "name": "", - "type": "address", - "internalType": "address" + "type": "uint32", + "internalType": "uint32" } ], "stateMutability": "view" }, { "type": "function", - "name": "getAppLatestReleaseBlockNumber", + "name": "getAppOperatorSetId", "inputs": [ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [ @@ -356,12 +519,12 @@ }, { "type": "function", - "name": "getAppOperatorSetId", + "name": "getAppPendingReleaseBlockNumber", "inputs": [ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [ @@ -380,14 +543,14 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [ { "name": "", "type": "uint8", - "internalType": "enumIAppController.AppStatus" + "internalType": "enum IAppController.AppStatus" } ], "stateMutability": "view" @@ -411,12 +574,12 @@ { "name": "apps", "type": "address[]", - "internalType": "contractIApp[]" + "internalType": "contract IApp[]" }, { "name": "appConfigsMem", "type": "tuple[]", - "internalType": "structIAppController.AppConfig[]", + "internalType": "struct IAppController.AppConfig[]", "components": [ { "name": "creator", @@ -433,10 +596,15 @@ "type": "uint32", "internalType": "uint32" }, + { + "name": "pendingReleaseBlockNumber", + "type": "uint32", + "internalType": "uint32" + }, { "name": "status", "type": "uint8", - "internalType": "enumIAppController.AppStatus" + "internalType": "enum IAppController.AppStatus" } ] } @@ -467,12 +635,12 @@ { "name": "apps", "type": "address[]", - "internalType": "contractIApp[]" + "internalType": "contract IApp[]" }, { "name": "appConfigsMem", "type": "tuple[]", - "internalType": "structIAppController.AppConfig[]", + "internalType": "struct IAppController.AppConfig[]", "components": [ { "name": "creator", @@ -489,10 +657,15 @@ "type": "uint32", "internalType": "uint32" }, + { + "name": "pendingReleaseBlockNumber", + "type": "uint32", + "internalType": "uint32" + }, { "name": "status", "type": "uint8", - "internalType": "enumIAppController.AppStatus" + "internalType": "enum IAppController.AppStatus" } ] } @@ -523,12 +696,12 @@ { "name": "apps", "type": "address[]", - "internalType": "contractIApp[]" + "internalType": "contract IApp[]" }, { "name": "appConfigsMem", "type": "tuple[]", - "internalType": "structIAppController.AppConfig[]", + "internalType": "struct IAppController.AppConfig[]", "components": [ { "name": "creator", @@ -545,10 +718,15 @@ "type": "uint32", "internalType": "uint32" }, + { + "name": "pendingReleaseBlockNumber", + "type": "uint32", + "internalType": "uint32" + }, { "name": "status", "type": "uint8", - "internalType": "enumIAppController.AppStatus" + "internalType": "enum IAppController.AppStatus" } ] } @@ -579,12 +757,12 @@ { "name": "apps", "type": "address[]", - "internalType": "contractIApp[]" + "internalType": "contract IApp[]" }, { "name": "appConfigsMem", "type": "tuple[]", - "internalType": "structIAppController.AppConfig[]", + "internalType": "struct IAppController.AppConfig[]", "components": [ { "name": "creator", @@ -601,16 +779,59 @@ "type": "uint32", "internalType": "uint32" }, + { + "name": "pendingReleaseBlockNumber", + "type": "uint32", + "internalType": "uint32" + }, { "name": "status", "type": "uint8", - "internalType": "enumIAppController.AppStatus" + "internalType": "enum IAppController.AppStatus" } ] } ], "stateMutability": "view" }, + { + "type": "function", + "name": "getBillingAccount", + "inputs": [ + { + "name": "app", + "type": "address", + "internalType": "contract IApp" + } + ], + "outputs": [ + { + "name": "", + "type": "address", + "internalType": "address" + } + ], + "stateMutability": "view" + }, + { + "type": "function", + "name": "getBillingType", + "inputs": [ + { + "name": "app", + "type": "address", + "internalType": "contract IApp" + } + ], + "outputs": [ + { + "name": "", + "type": "uint8", + "internalType": "enum IAppController.BillingType" + } + ], + "stateMutability": "view" + }, { "type": "function", "name": "getMaxActiveAppsPerUser", @@ -677,7 +898,7 @@ { "name": "", "type": "address", - "internalType": "contractIPermissionController" + "internalType": "contract IPermissionController" } ], "stateMutability": "view" @@ -690,7 +911,7 @@ { "name": "", "type": "address", - "internalType": "contractIReleaseManager" + "internalType": "contract IReleaseManager" } ], "stateMutability": "view" @@ -733,7 +954,7 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [], @@ -746,7 +967,7 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [], @@ -764,7 +985,7 @@ { "name": "apps", "type": "address[]", - "internalType": "contractIApp[]" + "internalType": "contract IApp[]" } ], "outputs": [], @@ -777,7 +998,7 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [], @@ -790,7 +1011,7 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "outputs": [], @@ -803,7 +1024,7 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" }, { "name": "metadataURI", @@ -821,22 +1042,22 @@ { "name": "app", "type": "address", - "internalType": "contractIApp" + "internalType": "contract IApp" }, { "name": "release", "type": "tuple", - "internalType": "structIAppController.Release", + "internalType": "struct IAppController.Release", "components": [ { "name": "rmsRelease", "type": "tuple", - "internalType": "structIReleaseManagerTypes.Release", + "internalType": "struct IReleaseManagerTypes.Release", "components": [ { "name": "artifacts", "type": "tuple[]", - "internalType": "structIReleaseManagerTypes.Artifact[]", + "internalType": "struct IReleaseManagerTypes.Artifact[]", "components": [ { "name": "digest", @@ -866,6 +1087,62 @@ "name": "encryptedEnv", "type": "bytes", "internalType": "bytes" + }, + { + "name": "containerPolicy", + "type": "tuple", + "internalType": "struct IAppController.ContainerPolicy", + "components": [ + { + "name": "args", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "cmdOverride", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "env", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "envOverride", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "restartPolicy", + "type": "string", + "internalType": "string" + } + ] } ] } @@ -906,7 +1183,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" }, { "name": "operatorSetId", @@ -925,7 +1202,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" }, { "name": "metadataURI", @@ -944,7 +1221,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "anonymous": false @@ -957,7 +1234,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "anonymous": false @@ -970,7 +1247,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "anonymous": false @@ -983,7 +1260,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "anonymous": false @@ -996,7 +1273,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" } ], "anonymous": false @@ -1009,7 +1286,7 @@ "name": "app", "type": "address", "indexed": true, - "internalType": "contractIApp" + "internalType": "contract IApp" }, { "name": "rmsReleaseId", @@ -1021,17 +1298,17 @@ "name": "release", "type": "tuple", "indexed": false, - "internalType": "structIAppController.Release", + "internalType": "struct IAppController.Release", "components": [ { "name": "rmsRelease", "type": "tuple", - "internalType": "structIReleaseManagerTypes.Release", + "internalType": "struct IReleaseManagerTypes.Release", "components": [ { "name": "artifacts", "type": "tuple[]", - "internalType": "structIReleaseManagerTypes.Artifact[]", + "internalType": "struct IReleaseManagerTypes.Artifact[]", "components": [ { "name": "digest", @@ -1061,6 +1338,62 @@ "name": "encryptedEnv", "type": "bytes", "internalType": "bytes" + }, + { + "name": "containerPolicy", + "type": "tuple", + "internalType": "struct IAppController.ContainerPolicy", + "components": [ + { + "name": "args", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "cmdOverride", + "type": "string[]", + "internalType": "string[]" + }, + { + "name": "env", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "envOverride", + "type": "tuple[]", + "internalType": "struct IAppController.EnvVar[]", + "components": [ + { + "name": "key", + "type": "string", + "internalType": "string" + }, + { + "name": "value", + "type": "string", + "internalType": "string" + } + ] + }, + { + "name": "restartPolicy", + "type": "string", + "internalType": "string" + } + ] } ] } @@ -1112,6 +1445,25 @@ ], "anonymous": false }, + { + "type": "event", + "name": "UpgradeConfirmed", + "inputs": [ + { + "name": "app", + "type": "address", + "indexed": true, + "internalType": "contract IApp" + }, + { + "name": "pendingReleaseBlockNumber", + "type": "uint32", + "indexed": false, + "internalType": "uint32" + } + ], + "anonymous": false + }, { "type": "error", "name": "AccountHasActiveApps", @@ -1167,6 +1519,11 @@ "name": "MoreThanOneArtifact", "inputs": [] }, + { + "type": "error", + "name": "NoPendingUpgrade", + "inputs": [] + }, { "type": "error", "name": "SignatureExpired", diff --git a/packages/sdk/src/client/common/contract/caller.ts b/packages/sdk/src/client/common/contract/caller.ts index 0999f9f0..88f17d07 100644 --- a/packages/sdk/src/client/common/contract/caller.ts +++ b/packages/sdk/src/client/common/contract/caller.ts @@ -254,6 +254,7 @@ export async function prepareDeployBatch( }, publicEnv: bytesToHex(release.publicEnv) as Hex, encryptedEnv: bytesToHex(release.encryptedEnv) as Hex, + containerPolicy: release.containerPolicy, }; const functionName = options.billTo === "app" ? "createAppWithIsolatedBilling" : "createApp"; @@ -750,6 +751,7 @@ export async function prepareUpgradeBatch( }, publicEnv: bytesToHex(release.publicEnv) as Hex, encryptedEnv: bytesToHex(release.encryptedEnv) as Hex, + containerPolicy: release.containerPolicy, }; const upgradeData = encodeFunctionData({ diff --git a/packages/sdk/src/client/common/release/prebuilt.ts b/packages/sdk/src/client/common/release/prebuilt.ts index ca91bf89..bfa5e119 100644 --- a/packages/sdk/src/client/common/release/prebuilt.ts +++ b/packages/sdk/src/client/common/release/prebuilt.ts @@ -1,6 +1,7 @@ import { parseAndValidateEnvFile } from "../env/parser"; import { encryptRSAOAEPAndAES256GCM, getAppProtectedHeaders } from "../encryption/kms"; import { getKMSKeysForEnvironment } from "../utils/keys"; +import { EMPTY_CONTAINER_POLICY } from "../types"; import type { EnvironmentConfig, Logger, Release } from "../types"; export interface CreateReleaseFromImageDigestOptions { @@ -74,6 +75,7 @@ export async function createReleaseFromImageDigest( }, publicEnv: new Uint8Array(Buffer.from(JSON.stringify(publicEnv))), encryptedEnv: new Uint8Array(Buffer.from(encryptedEnvStr)), + containerPolicy: EMPTY_CONTAINER_POLICY, }; } diff --git a/packages/sdk/src/client/common/release/prepare.ts b/packages/sdk/src/client/common/release/prepare.ts index 59fbc70e..2cc954c3 100644 --- a/packages/sdk/src/client/common/release/prepare.ts +++ b/packages/sdk/src/client/common/release/prepare.ts @@ -14,7 +14,7 @@ import { REGISTRY_PROPAGATION_WAIT_SECONDS } from "../constants"; import { parseAndValidateEnvFile } from "../env/parser"; -import { Release, EnvironmentConfig, Logger, AppId } from "../types"; +import { Release, EnvironmentConfig, Logger, AppId, EMPTY_CONTAINER_POLICY } from "../types"; export interface PrepareReleaseOptions { dockerfilePath?: string; @@ -177,6 +177,7 @@ export async function prepareRelease( }, publicEnv: new Uint8Array(Buffer.from(JSON.stringify(publicEnv))), encryptedEnv: new Uint8Array(Buffer.from(encryptedEnvStr)), + containerPolicy: EMPTY_CONTAINER_POLICY, }; return { diff --git a/packages/sdk/src/client/common/types/index.ts b/packages/sdk/src/client/common/types/index.ts index c42a8d71..9f7165aa 100644 --- a/packages/sdk/src/client/common/types/index.ts +++ b/packages/sdk/src/client/common/types/index.ts @@ -246,6 +246,33 @@ export interface EnvironmentConfig { usdcCreditsAddress?: Address; } +/** + * Container execution policy carried on a release. The AppController does not + * read these fields on-chain — they are emitted on the AppUpgraded/AppCreated + * release event and consumed off-chain by the platform/operator. The CLI does + * not currently surface any of these knobs, so an empty policy is sent (see + * EMPTY_CONTAINER_POLICY). The field is still required because it is part of + * the AppController `Release` struct ABI; omitting it shifts the selector and + * the on-chain call reverts in the dispatcher. + */ +export interface ContainerPolicy { + args: string[]; + cmdOverride: string[]; + env: Array<{ key: string; value: string }>; + envOverride: Array<{ key: string; value: string }>; + restartPolicy: string; +} + +/** An empty container policy — preserves the CLI's pre-existing behavior of not + * overriding container args/cmd/env or setting a restart policy. */ +export const EMPTY_CONTAINER_POLICY: ContainerPolicy = { + args: [], + cmdOverride: [], + env: [], + envOverride: [], + restartPolicy: "", +}; + export interface Release { rmsRelease: { artifacts: Array<{ @@ -256,6 +283,7 @@ export interface Release { }; publicEnv: Uint8Array; // JSON bytes encryptedEnv: Uint8Array; // Encrypted string bytes + containerPolicy: ContainerPolicy; } export interface ParsedEnvironment {