@junobuild/admin
Version:
A library for interfacing with admin features of Juno
4 lines • 146 kB
Source Map (JSON)
{
"version": 3,
"sources": ["../../src/errors/upgrade.errors.ts", "../../src/errors/version.errors.ts", "../../src/helpers/crypto.helpers.ts", "../../src/helpers/package.helpers.ts", "../../src/helpers/version.helpers.ts", "../../src/helpers/wasm.helpers.ts", "../../src/schemas/build.ts", "../../src/schemas/releases.ts", "../../src/api/mission-control.api.ts", "../../src/utils/controllers.utils.ts", "../../src/services/mission-control.controllers.services.ts", "../../src/services/mission-control.upgrade.services.ts", "../../src/constants/upgrade.constants.ts", "../../src/handlers/upgrade.handlers.ts", "../../src/api/ic.api.ts", "../../src/types/upgrade.ts", "../../src/handlers/upgrade.chunks.handlers.ts", "../../src/handlers/upgrade.single.handlers.ts", "../../src/utils/idl.utils.ts", "../../src/services/mission-control.version.services.ts", "../../src/services/package.services.ts", "../../src/services/module.upgrade.services.ts", "../../src/api/orbiter.api.ts", "../../src/services/orbiter.controllers.services.ts", "../../src/services/orbiter.memory.services.ts", "../../src/services/orbiter.upgrade.services.ts", "../../src/services/orbiter.version.services.ts", "../../src/api/satellite.api.ts", "../../src/services/satellite.assets.services.ts", "../../src/services/satellite.config.services.ts", "../../src/utils/config.utils.ts", "../../src/utils/memory.utils.ts", "../../src/services/satellite.controllers.services.ts", "../../src/services/satellite.docs.services.ts", "../../src/services/satellite.domains.services.ts", "../../src/services/satellite.memory.services.ts", "../../src/utils/rule.utils.ts", "../../src/constants/rules.constants.ts", "../../src/services/satellite.rules.services.ts", "../../src/services/satellite.upgrade.services.ts", "../../src/services/satellite.version.services.ts"],
"sourcesContent": ["export class UpgradeCodeUnchangedError extends Error {\n constructor() {\n super(\n 'The Wasm code for the upgrade is identical to the code currently installed. No upgrade is necessary.'\n );\n }\n}\n", "import {\n JUNO_PACKAGE_MISSION_CONTROL_ID,\n JUNO_PACKAGE_ORBITER_ID,\n JUNO_PACKAGE_SATELLITE_ID\n} from '@junobuild/config';\n\nexport class SatelliteMissingDependencyError extends Error {\n constructor() {\n super(`Invalid dependency tree: required module ${JUNO_PACKAGE_SATELLITE_ID} is missing.`);\n }\n}\n\nexport class MissionControlVersionError extends Error {\n constructor() {\n super(`Invalid package: the provided module name is not ${JUNO_PACKAGE_MISSION_CONTROL_ID}.`);\n }\n}\n\nexport class OrbiterVersionError extends Error {\n constructor() {\n super(`Invalid package: the provided module name is not ${JUNO_PACKAGE_ORBITER_ID}.`);\n }\n}\n", "// Sources:\n// https://stackoverflow.com/a/70891826/5404186\n// https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest\n\nconst digestSha256 = (data: ArrayBuffer | Uint8Array<ArrayBuffer>): Promise<ArrayBuffer> =>\n crypto.subtle.digest('SHA-256', data);\n\nconst sha256ToHex = (hashBuffer: ArrayBuffer): string => {\n const hashArray = Array.from(new Uint8Array(hashBuffer));\n return hashArray.map((b) => b.toString(16).padStart(2, '0')).join('');\n};\n\nexport const blobSha256 = async (blob: Blob): Promise<string> => {\n const hashBuffer = await digestSha256(await blob.arrayBuffer());\n return sha256ToHex(hashBuffer);\n};\n\nexport const uint8ArraySha256 = async (data: Uint8Array): Promise<string> => {\n const hashBuffer = await digestSha256(data as Uint8Array<ArrayBuffer>);\n return sha256ToHex(hashBuffer);\n};\n", "import type {JunoPackageDependencies} from '@junobuild/config';\n\n/**\n * Finds a specific dependency in a `JunoPackageDependencies` map.\n *\n * @param {Object} params - The parameters for the search.\n * @param {string} params.dependencyId - The ID of the dependency to look for.\n * @param {JunoPackageDependencies | undefined} params.dependencies - The full list of dependencies, or `undefined`.\n *\n * @returns {[string, string] | undefined} A tuple containing the dependency ID and version if found, or `undefined` if not found or no dependencies are present.\n */\nexport const findJunoPackageDependency = ({\n dependencyId,\n dependencies\n}: {\n dependencyId: string;\n dependencies: JunoPackageDependencies | undefined;\n}): [string, string] | undefined =>\n Object.entries(dependencies ?? {}).find(([key, _]) => key === dependencyId);\n", "import {major, minor, patch} from 'semver';\n\n/**\n * Checks if the selected version can be upgraded from the current version.\n * @param {Object} params - The parameters for the version check.\n * @param {string} params.currentVersion - The current version.\n * @param {string} params.selectedVersion - The selected version.\n * @returns {Object} An object indicating whether the upgrade can proceed.\n * @returns {boolean} returns.canUpgrade - Whether the selected version can be upgraded from the current version.\n */\nexport const checkUpgradeVersion = ({\n currentVersion,\n selectedVersion\n}: {\n currentVersion: string;\n selectedVersion: string;\n}): {canUpgrade: boolean} => {\n const currentMajor = major(currentVersion);\n const selectedMajor = major(selectedVersion);\n const currentMinor = minor(currentVersion);\n const selectedMinor = minor(selectedVersion);\n const currentPath = patch(currentVersion);\n const selectedPath = patch(selectedVersion);\n\n if (\n currentMajor < selectedMajor - 1 ||\n currentMinor < selectedMinor - 1 ||\n currentPath < selectedPath - 1\n ) {\n return {canUpgrade: false};\n }\n\n return {canUpgrade: true};\n};\n", "import {type JunoPackage, JUNO_PACKAGE_SATELLITE_ID, JunoPackageSchema} from '@junobuild/config';\nimport {isNullish, nonNullish} from '@junobuild/utils';\nimport type {BuildType} from '../schemas/build';\nimport {findJunoPackageDependency} from './package.helpers';\n\n/**\n * Extracts the build type from a provided Juno package or falls back to a deprecated detection method.\n *\n * @param {Object} params\n * @param {JunoPackage | undefined} params.junoPackage - The parsed Juno package metadata.\n * @param {Uint8Array} params.wasm - The WASM binary to inspect if no package is provided.\n * @returns {Promise<BuildType | undefined>} The build type (`'stock'` or `'extended'`) or `undefined` if undetermined.\n */\nexport const extractBuildType = async ({\n junoPackage,\n wasm\n}: {\n junoPackage: JunoPackage | undefined;\n wasm: Uint8Array;\n}): Promise<BuildType | undefined> => {\n if (isNullish(junoPackage)) {\n return await readDeprecatedBuildType({wasm});\n }\n\n const {name, dependencies} = junoPackage;\n\n if (name === JUNO_PACKAGE_SATELLITE_ID) {\n return 'stock';\n }\n\n const satelliteDependency = findJunoPackageDependency({\n dependencies,\n dependencyId: JUNO_PACKAGE_SATELLITE_ID\n });\n\n return nonNullish(satelliteDependency) ? 'extended' : undefined;\n};\n\n/**\n * @deprecated Modern WASM build use JunoPackage.\n */\nconst readDeprecatedBuildType = async ({\n wasm\n}: {\n wasm: Uint8Array;\n}): Promise<BuildType | undefined> => {\n const buildType = await customSection({wasm, sectionName: 'icp:public juno:build'});\n\n return nonNullish(buildType) && ['stock', 'extended'].includes(buildType)\n ? (buildType as BuildType)\n : undefined;\n};\n\n/**\n * Reads and parses the Juno package from the custom section of a WASM binary.\n *\n * @param {Object} params\n * @param {Uint8Array} params.wasm - The WASM binary containing the embedded custom section.\n * @returns {Promise<JunoPackage | undefined>} The parsed Juno package if present and valid, otherwise `undefined`.\n */\nexport const readCustomSectionJunoPackage = async ({\n wasm\n}: {\n wasm: Uint8Array;\n}): Promise<JunoPackage | undefined> => {\n const section = await customSection({wasm, sectionName: 'icp:public juno:package'});\n\n if (isNullish(section)) {\n return undefined;\n }\n\n const pkg = JSON.parse(section);\n\n const {success, data} = JunoPackageSchema.safeParse(pkg);\n return success ? data : undefined;\n};\n\nconst customSection = async ({\n sectionName,\n wasm\n}: {\n sectionName: string;\n wasm: Uint8Array;\n}): Promise<string | undefined> => {\n const wasmModule = await WebAssembly.compile(wasm as Uint8Array<ArrayBuffer>);\n\n const pkgSections = WebAssembly.Module.customSections(wasmModule, sectionName);\n\n const [pkgBuffer] = pkgSections;\n\n return nonNullish(pkgBuffer) ? new TextDecoder().decode(pkgBuffer) : undefined;\n};\n", "import * as z from 'zod';\n\n/**\n * Represents the type of build, stock or extended.\n */\nexport const BuildTypeSchema = z.enum(['stock', 'extended']);\n\n/**\n * Represents the type of build.\n * @typedef {'stock' | 'extended'} BuildType\n */\nexport type BuildType = z.infer<typeof BuildTypeSchema>;\n", "import * as z from 'zod';\n\n/**\n * A schema for validating a version string in `x.y.z` format.\n *\n * Examples of valid versions:\n * - 0.1.0\"\n * - 2.3.4\n */\nexport const MetadataVersionSchema = z.string().refine((val) => /^\\d+\\.\\d+\\.\\d+$/.test(val), {\n message: 'Version does not match x.y.z format'\n});\n\n/**\n * A version string in `x.y.z` format.\n */\nexport type MetadataVersion = z.infer<typeof MetadataVersionSchema>;\n\n/**\n * A schema representing the metadata of a single release.\n *\n * Includes the version of the release itself (tag) and the versions\n * of all modules bundled with it.\n */\nexport const ReleaseMetadataSchema = z.strictObject({\n /**\n * Unique version identifier for the release, following the `x.y.z` format.\n * @type {MetadataVersion}\n */\n tag: MetadataVersionSchema,\n\n /**\n * The version of the console included in the release.\n * @type {MetadataVersion}\n */\n console: MetadataVersionSchema,\n\n /**\n * Version of the Observatory module included in the release.\n * This field is optional because it was introduced in Juno v0.0.10.\n *\n * @type {MetadataVersion | undefined}\n */\n observatory: MetadataVersionSchema.optional(),\n\n /**\n * Version of the Mission Control module included in the release.\n * @type {MetadataVersion}\n */\n mission_control: MetadataVersionSchema,\n\n /**\n * Version of the Satellite module included in the release.\n * @type {MetadataVersion}\n */\n satellite: MetadataVersionSchema,\n\n /**\n * Version of the Orbiter module included in the release.\n * This field is optional because it was introduced in Juno v0.0.17.\n *\n * @type {MetadataVersion | undefined}\n */\n orbiter: MetadataVersionSchema.optional(),\n\n /**\n * Version of the Sputnik module included in the release.\n * This field is optional because it was introduced in Juno v0.0.47.\n *\n * @type {MetadataVersion | undefined}\n */\n sputnik: MetadataVersionSchema.optional()\n});\n\n/**\n * The metadata for a release provided by Juno.\n */\nexport type ReleaseMetadata = z.infer<typeof ReleaseMetadataSchema>;\n\n/**\n * A schema representing the list of releases provided by Juno.\n *\n * Rules:\n * - The list must contain at least one release.\n * - Each release must have a unique `tag` (version identifier).\n * - The same module version can appear in multiple releases, as not every release\n * necessarily publishes a new version of each module.\n *\n * Validation:\n * - Ensures no duplicate `tag` values across the list of releases.\n */\nexport const ReleasesSchema = z\n .array(ReleaseMetadataSchema)\n .min(1)\n .refine((releases) => new Set(releases.map(({tag}) => tag)).size === releases.length, {\n message: 'A release tag appears multiple times but must be unique'\n });\n\n/**\n * The list of releases provided by Juno.\n */\nexport type Releases = z.infer<typeof ReleasesSchema>;\n\n/**\n * A schema for the list of all versions across releases.\n *\n * Rules:\n * - The list must contain at least one release.\n */\nexport const MetadataVersionsSchema = z.array(MetadataVersionSchema).min(1);\n\n/**\n * List of all versions across releases.\n */\nexport type MetadataVersions = z.infer<typeof MetadataVersionsSchema>;\n\n/**\n * A schema representing the metadata for multiple releases provided by Juno.\n */\nexport const ReleasesMetadataSchema = z.strictObject({\n /**\n * List of all Mission Control versions across releases.\n * @type {MetadataVersion}\n */\n mission_controls: MetadataVersionsSchema,\n\n /**\n * List of all Satellite versions across releases.\n * @type {MetadataVersion}\n */\n satellites: MetadataVersionsSchema,\n\n /**\n * List of all Orbiter versions across releases.\n * @type {MetadataVersion}\n */\n orbiters: MetadataVersionsSchema,\n\n /**\n * List of release metadata objects, each representing one release.\n */\n releases: ReleasesSchema\n});\n\n/**\n * The metadata for multiple releases provided by Juno.\n */\nexport type ReleasesMetadata = z.infer<typeof ReleasesMetadataSchema>;\n", "import type {Principal} from '@icp-sdk/core/principal';\nimport {\n type MissionControlDid,\n type MissionControlParameters,\n getDeprecatedMissionControlVersionActor,\n getMissionControlActor\n} from '@junobuild/ic-client/actor';\n\n/**\n * @deprecated - Replaced in Mission Control > v0.0.14 with public custom section juno:package\n */\nexport const version = async ({\n missionControl\n}: {\n missionControl: MissionControlParameters;\n}): Promise<string> => {\n const {version} = await getDeprecatedMissionControlVersionActor(missionControl);\n return version();\n};\n\nexport const getUser = async ({\n missionControl\n}: {\n missionControl: MissionControlParameters;\n}): Promise<Principal> => {\n const {get_user} = await getMissionControlActor(missionControl);\n return get_user();\n};\n\nexport const listControllers = async ({\n missionControl\n}: {\n missionControl: MissionControlParameters;\n}): Promise<[Principal, MissionControlDid.AccessKey][]> => {\n const {list_mission_control_controllers} = await getMissionControlActor(missionControl);\n return list_mission_control_controllers();\n};\n\nexport const setSatellitesController = async ({\n missionControl,\n satelliteIds,\n controllerIds,\n controller\n}: {\n missionControl: MissionControlParameters;\n satelliteIds: Principal[];\n controllerIds: Principal[];\n controller: MissionControlDid.SetAccessKey;\n}) => {\n const {set_satellites_controllers} = await getMissionControlActor(missionControl);\n return set_satellites_controllers(satelliteIds, controllerIds, controller);\n};\n\nexport const setMissionControlController = async ({\n missionControl,\n controllerIds,\n controller\n}: {\n missionControl: MissionControlParameters;\n controllerIds: Principal[];\n controller: MissionControlDid.SetAccessKey;\n}) => {\n const {set_mission_control_controllers} = await getMissionControlActor(missionControl);\n return set_mission_control_controllers(controllerIds, controller);\n};\n", "import {Principal} from '@icp-sdk/core/principal';\nimport type {MissionControlDid} from '@junobuild/ic-client/actor';\nimport {nonNullish, toNullable} from '@junobuild/utils';\nimport type {SetControllerParams} from '../types/controllers';\n\nexport const mapSetControllerParams = ({\n controllerId,\n profile\n}: SetControllerParams): {\n controllerIds: Principal[];\n controller: MissionControlDid.SetAccessKey;\n} => ({\n controllerIds: [Principal.fromText(controllerId)],\n controller: toSetController(profile)\n});\n\nconst toSetController = (profile: string | null | undefined): MissionControlDid.SetAccessKey => ({\n metadata: nonNullish(profile) && profile !== '' ? [['profile', profile]] : [],\n expires_at: toNullable<bigint>(undefined),\n scope: {Admin: null},\n kind: toNullable()\n});\n", "import type {Principal} from '@icp-sdk/core/principal';\nimport type {MissionControlDid, MissionControlParameters} from '@junobuild/ic-client/actor';\nimport {\n listControllers,\n setMissionControlController as setMissionControlControllerApi,\n setSatellitesController as setSatellitesControllerApi\n} from '../api/mission-control.api';\nimport type {SetControllerParams} from '../types/controllers';\nimport {mapSetControllerParams} from '../utils/controllers.utils';\n\n/**\n * Sets the controller for the specified satellites.\n * @param {Object} params - The parameters for setting the satellites controller.\n * @param {MissionControlParameters} params.missionControl - The Mission Control parameters.\n * @param {Principal[]} params.satelliteIds - The IDs of the satellites.\n * @param {SetControllerParams} params - Additional parameters for setting the controller.\n * @returns {Promise<void>} A promise that resolves when the controller is set.\n */\nexport const setSatellitesController = ({\n controllerId,\n profile,\n ...rest\n}: {\n missionControl: MissionControlParameters;\n satelliteIds: Principal[];\n} & SetControllerParams): Promise<void> =>\n setSatellitesControllerApi({\n ...rest,\n ...mapSetControllerParams({controllerId, profile})\n });\n\n/**\n * Sets the controller for Mission Control.\n * @param {Object} params - The parameters for setting the Mission Control controller.\n * @param {MissionControlParameters} params.missionControl - The Mission Control parameters.\n * @param {SetControllerParams} params - Additional parameters for setting the controller.\n * @returns {Promise<void>} A promise that resolves when the controller is set.\n */\nexport const setMissionControlController = ({\n controllerId,\n profile,\n ...rest\n}: {\n missionControl: MissionControlParameters;\n} & SetControllerParams): Promise<void> =>\n setMissionControlControllerApi({\n ...rest,\n ...mapSetControllerParams({controllerId, profile})\n });\n\n/**\n * Lists the controllers of Mission Control.\n * @param {Object} params - The parameters for listing the controllers.\n * @param {MissionControlParameters} params.missionControl - The Mission Control parameters.\n * @returns {Promise<[Principal, Controller][]>} A promise that resolves to a list of controllers.\n */\nexport const listMissionControlControllers = (params: {\n missionControl: MissionControlParameters;\n}): Promise<[Principal, MissionControlDid.AccessKey][]> => listControllers(params);\n", "import type {MissionControlParameters} from '@junobuild/ic-client/actor';\nimport {toPrincipal} from '@junobuild/ic-client/utils';\nimport {getUser} from '../api/mission-control.api';\nimport {INSTALL_MODE_UPGRADE} from '../constants/upgrade.constants';\nimport {upgrade} from '../handlers/upgrade.handlers';\nimport type {UpgradeCodeParams} from '../types/upgrade';\nimport {encoreIDLUser} from '../utils/idl.utils';\n\n/**\n * Upgrades the Mission Control with the provided WASM module.\n * @param {Object} params - The parameters for upgrading the Mission Control.\n * @param {MissionControlParameters} params.missionControl - The Mission Control parameters, including the actor and mission control ID.\n * @param {Uint8Array} params.wasmModule - The WASM module to be installed during the upgrade.\n * @param {boolean} [params.preClearChunks] - Optional. Whether to force clearing chunks before uploading a chunked WASM module. Recommended if the WASM exceeds 2MB.\n * @param {boolean} [params.takeSnapshot=true] - Optional. Whether to take a snapshot before performing the upgrade. Defaults to true.\n * @param {function} [params.onProgress] - Optional. Callback function to report progress during the upgrade process.\n * @throws {Error} Will throw an error if the mission control principal is not defined.\n * @returns {Promise<void>} Resolves when the upgrade process is complete.\n */\nexport const upgradeMissionControl = async ({\n missionControl,\n ...rest\n}: {\n missionControl: MissionControlParameters;\n} & Pick<\n UpgradeCodeParams,\n 'wasmModule' | 'preClearChunks' | 'takeSnapshot' | 'onProgress'\n>): Promise<void> => {\n const user = await getUser({missionControl});\n\n const {missionControlId, ...actor} = missionControl;\n\n if (!missionControlId) {\n throw new Error('No mission control principal defined.');\n }\n\n const arg = encoreIDLUser(user);\n\n await upgrade({\n actor,\n canisterId: toPrincipal(missionControlId),\n arg,\n mode: INSTALL_MODE_UPGRADE,\n ...rest\n });\n};\n", "import type {IcManagementDid} from '@icp-sdk/canisters/ic-management';\n\nexport const SIMPLE_INSTALL_MAX_WASM_SIZE = 2_000_000;\nexport const INSTALL_MAX_CHUNK_SIZE = 1_000_000;\n\nexport const INSTALL_MODE_RESET: IcManagementDid.canister_install_mode = {reinstall: null};\n\nexport const INSTALL_MODE_UPGRADE: IcManagementDid.canister_install_mode = {\n upgrade: [{skip_pre_upgrade: [false], wasm_memory_persistence: [{replace: null}]}]\n};\n", "import {fromNullable, isNullish, uint8ArrayToHexString} from '@junobuild/utils';\nimport {\n canisterStart,\n canisterStatus,\n canisterStop,\n listCanisterSnapshots,\n takeCanisterSnapshot\n} from '../api/ic.api';\nimport {SIMPLE_INSTALL_MAX_WASM_SIZE} from '../constants/upgrade.constants';\nimport {UpgradeCodeUnchangedError} from '../errors/upgrade.errors';\nimport {uint8ArraySha256} from '../helpers/crypto.helpers';\nimport {type UpgradeCodeParams, UpgradeCodeProgressStep} from '../types/upgrade';\nimport {upgradeChunkedCode} from './upgrade.chunks.handlers';\nimport {upgradeSingleChunkCode} from './upgrade.single.handlers';\n\nexport const upgrade = async ({\n wasmModule,\n canisterId,\n actor,\n onProgress,\n takeSnapshot = true,\n ...rest\n}: UpgradeCodeParams & {reset?: boolean}) => {\n // 1. We verify that the code to be installed is different from the code already deployed. If the codes are identical, we skip the installation.\n // TODO: unless mode is reinstall\n const assert = async () => await assertExistingCode({wasmModule, canisterId, actor, ...rest});\n await execute({fn: assert, onProgress, step: UpgradeCodeProgressStep.AssertingExistingCode});\n\n // 2. We stop the canister to prepare for the upgrade.\n const stop = async () => await canisterStop({canisterId, actor});\n await execute({fn: stop, onProgress, step: UpgradeCodeProgressStep.StoppingCanister});\n\n try {\n // 3. We take a snapshot - create a backup - unless the dev opted-out\n const snapshot = async () =>\n takeSnapshot ? await createSnapshot({canisterId, actor}) : Promise.resolve();\n await execute({fn: snapshot, onProgress, step: UpgradeCodeProgressStep.TakingSnapshot});\n\n // 4. Upgrading code: If the WASM is > 2MB we proceed with the chunked installation otherwise we use the original single chunk installation method.\n const upgrade = async () => await upgradeCode({wasmModule, canisterId, actor, ...rest});\n await execute({fn: upgrade, onProgress, step: UpgradeCodeProgressStep.UpgradingCode});\n } finally {\n // 5. We restart the canister to finalize the process.\n const restart = async () => await canisterStart({canisterId, actor});\n await execute({fn: restart, onProgress, step: UpgradeCodeProgressStep.RestartingCanister});\n }\n};\n\nconst execute = async ({\n fn,\n step,\n onProgress\n}: {fn: () => Promise<void>; step: UpgradeCodeProgressStep} & Pick<\n UpgradeCodeParams,\n 'onProgress'\n>) => {\n onProgress?.({\n step,\n state: 'in_progress'\n });\n\n try {\n await fn();\n\n onProgress?.({\n step,\n state: 'success'\n });\n } catch (err: unknown) {\n onProgress?.({\n step,\n state: 'error'\n });\n\n throw err;\n }\n};\n\nconst assertExistingCode = async ({\n actor,\n canisterId,\n wasmModule,\n reset\n}: Pick<UpgradeCodeParams, 'actor' | 'canisterId' | 'wasmModule'> & {reset?: boolean}) => {\n // If we want to reinstall the module we are fine reinstalling the same version of the code\n if (reset === true) {\n return;\n }\n\n const {module_hash} = await canisterStatus({\n actor,\n canisterId\n });\n\n const installedHash = fromNullable(module_hash);\n\n if (isNullish(installedHash)) {\n return;\n }\n\n const newWasmModuleHash = await uint8ArraySha256(wasmModule);\n const existingWasmModuleHash = uint8ArrayToHexString(installedHash);\n\n if (newWasmModuleHash !== existingWasmModuleHash) {\n return;\n }\n\n throw new UpgradeCodeUnchangedError();\n};\n\nconst upgradeCode = async ({\n wasmModule,\n canisterId,\n actor,\n ...rest\n}: Omit<UpgradeCodeParams, 'onProgress'>) => {\n const upgradeType = (): 'chunked' | 'single' => {\n const blob = new Blob([wasmModule as Uint8Array<ArrayBuffer>]);\n return blob.size > SIMPLE_INSTALL_MAX_WASM_SIZE ? 'chunked' : 'single';\n };\n\n const fn = upgradeType() === 'chunked' ? upgradeChunkedCode : upgradeSingleChunkCode;\n await fn({wasmModule, canisterId, actor, ...rest});\n};\n\nconst createSnapshot = async (params: Pick<UpgradeCodeParams, 'canisterId' | 'actor'>) => {\n const snapshots = await listCanisterSnapshots(params);\n\n // TODO: currently only one snapshot per canister is supported on the IC\n await takeCanisterSnapshot({\n ...params,\n snapshotId: snapshots?.[0]?.id\n });\n};\n", "import {\n type CanisterStatusResponse,\n IcManagementCanister,\n type IcManagementDid,\n type InstallChunkedCodeParams,\n type InstallCodeParams,\n type UploadChunkParams\n} from '@icp-sdk/canisters/ic-management';\nimport {CanisterStatus} from '@icp-sdk/core/agent';\nimport {Principal} from '@icp-sdk/core/principal';\nimport {type ActorParameters, useOrInitAgent} from '@junobuild/ic-client/actor';\n\nexport const canisterStop = async ({\n canisterId,\n actor\n}: {\n canisterId: Principal;\n actor: ActorParameters;\n}): Promise<void> => {\n const agent = await useOrInitAgent(actor);\n\n const {stopCanister} = IcManagementCanister.create({\n agent\n });\n\n await stopCanister(canisterId);\n};\n\nexport const canisterStart = async ({\n canisterId,\n actor\n}: {\n canisterId: Principal;\n actor: ActorParameters;\n}): Promise<void> => {\n const agent = await useOrInitAgent(actor);\n\n const {startCanister} = IcManagementCanister.create({\n agent\n });\n\n await startCanister(canisterId);\n};\n\nexport const installCode = async ({\n actor,\n code\n}: {\n actor: ActorParameters;\n code: InstallCodeParams;\n}): Promise<void> => {\n const agent = await useOrInitAgent(actor);\n\n const {installCode} = IcManagementCanister.create({\n agent\n });\n\n return installCode(code);\n};\n\nexport const storedChunks = async ({\n actor,\n canisterId\n}: {\n actor: ActorParameters;\n canisterId: Principal;\n}): Promise<IcManagementDid.chunk_hash[]> => {\n const agent = await useOrInitAgent(actor);\n\n const {storedChunks} = IcManagementCanister.create({\n agent\n });\n\n return storedChunks({canisterId});\n};\n\nexport const clearChunkStore = async ({\n actor,\n canisterId\n}: {\n actor: ActorParameters;\n canisterId: Principal;\n}): Promise<void> => {\n const agent = await useOrInitAgent(actor);\n\n const {clearChunkStore} = IcManagementCanister.create({\n agent\n });\n\n return clearChunkStore({canisterId});\n};\n\nexport const uploadChunk = async ({\n actor,\n chunk\n}: {\n actor: ActorParameters;\n chunk: UploadChunkParams;\n}): Promise<IcManagementDid.chunk_hash> => {\n const agent = await useOrInitAgent(actor);\n\n const {uploadChunk} = IcManagementCanister.create({\n agent\n });\n\n return uploadChunk(chunk);\n};\n\nexport const installChunkedCode = async ({\n actor,\n code\n}: {\n actor: ActorParameters;\n code: InstallChunkedCodeParams;\n}): Promise<void> => {\n const agent = await useOrInitAgent(actor);\n\n const {installChunkedCode} = IcManagementCanister.create({\n agent\n });\n\n return installChunkedCode(code);\n};\n\nexport const canisterStatus = async ({\n actor,\n canisterId\n}: {\n actor: ActorParameters;\n canisterId: Principal;\n}): Promise<CanisterStatusResponse> => {\n const agent = await useOrInitAgent(actor);\n\n const {canisterStatus} = IcManagementCanister.create({\n agent\n });\n\n return canisterStatus({canisterId});\n};\n\nexport const canisterMetadata = async ({\n canisterId,\n path,\n ...rest\n}: ActorParameters & {\n canisterId: Principal | string;\n path: string;\n}): Promise<CanisterStatus.Status | undefined> => {\n const agent = await useOrInitAgent(rest);\n\n // TODO: Workaround for agent-js. Disable console.warn.\n // See https://github.com/dfinity/agent-js/issues/843\n const hideAgentJsConsoleWarn = globalThis.console.warn;\n globalThis.console.warn = (): null => null;\n\n const result = await CanisterStatus.request({\n canisterId: canisterId instanceof Principal ? canisterId : Principal.from(canisterId),\n agent,\n paths: [new CanisterStatus.CustomPath(path, path, 'utf-8')]\n });\n\n // Redo console.warn\n globalThis.console.warn = hideAgentJsConsoleWarn;\n\n return result.get(path);\n};\n\nexport const listCanisterSnapshots = async ({\n actor,\n canisterId\n}: {\n actor: ActorParameters;\n canisterId: Principal;\n}): Promise<IcManagementDid.list_canister_snapshots_result> => {\n const agent = await useOrInitAgent(actor);\n\n const {listCanisterSnapshots} = IcManagementCanister.create({\n agent\n });\n\n return listCanisterSnapshots({canisterId});\n};\n\nexport const takeCanisterSnapshot = async ({\n actor,\n ...rest\n}: {\n actor: ActorParameters;\n canisterId: Principal;\n snapshotId?: IcManagementDid.snapshot_id;\n}): Promise<IcManagementDid.take_canister_snapshot_result> => {\n const agent = await useOrInitAgent(actor);\n\n const {takeCanisterSnapshot} = IcManagementCanister.create({\n agent\n });\n\n return takeCanisterSnapshot(rest);\n};\n", "import type {IcManagementDid} from '@icp-sdk/canisters/ic-management';\nimport type {Principal} from '@icp-sdk/core/principal';\nimport type {ActorParameters} from '@junobuild/ic-client/actor';\n\nexport enum UpgradeCodeProgressStep {\n AssertingExistingCode,\n StoppingCanister,\n TakingSnapshot,\n UpgradingCode,\n RestartingCanister\n}\n\nexport type UpgradeCodeProgressState = 'in_progress' | 'success' | 'error';\n\nexport interface UpgradeCodeProgress {\n step: UpgradeCodeProgressStep;\n state: UpgradeCodeProgressState;\n}\n\nexport interface UpgradeCodeParams {\n actor: ActorParameters;\n canisterId: Principal;\n wasmModule: Uint8Array;\n arg: Uint8Array;\n mode: IcManagementDid.canister_install_mode;\n preClearChunks?: boolean;\n takeSnapshot?: boolean;\n onProgress?: (progress: UpgradeCodeProgress) => void;\n}\n", "import type {IcManagementDid} from '@icp-sdk/canisters/ic-management';\nimport {nonNullish, uint8ArrayToHexString} from '@junobuild/utils';\nimport {\n clearChunkStore,\n installChunkedCode,\n storedChunks as storedChunksApi,\n uploadChunk as uploadChunkApi\n} from '../api/ic.api';\nimport {INSTALL_MAX_CHUNK_SIZE} from '../constants/upgrade.constants';\nimport {blobSha256, uint8ArraySha256} from '../helpers/crypto.helpers';\nimport type {UpgradeCodeParams} from '../types/upgrade';\n\ninterface UploadChunkOrderId {\n orderId: number;\n}\n\ninterface UploadChunkParams extends UploadChunkOrderId {\n chunk: Blob;\n sha256: string;\n}\n\ninterface UploadChunkResult extends UploadChunkOrderId {\n chunkHash: IcManagementDid.chunk_hash;\n}\n\nexport const upgradeChunkedCode = async ({\n actor,\n canisterId,\n wasmModule,\n preClearChunks: userPreClearChunks,\n ...rest\n}: UpgradeCodeParams) => {\n // If the user want to clear - reset - any chunks that have been uploaded before we start by removing those.\n if (userPreClearChunks) {\n await clearChunkStore({actor, canisterId});\n }\n\n const wasmChunks = await wasmToChunks({wasmModule});\n\n const {uploadChunks, storedChunks, preClearChunks, postClearChunks} = await prepareUpload({\n actor,\n wasmChunks,\n canisterId\n });\n\n // Alright, let's start by clearing existing chunks if there are already stored chunks but, none are matching those we want to upload.\n if (preClearChunks) {\n await clearChunkStore({actor, canisterId});\n }\n\n // Upload chunks to the IC in batch - i.e. 12 chunks uploaded at a time.\n let chunkIds: UploadChunkResult[] = [];\n for await (const results of batchUploadChunks({\n uploadChunks,\n actor,\n canisterId\n })) {\n chunkIds = [...chunkIds, ...results];\n }\n\n // Install the chunked code.\n // \u26A0\uFE0F The order of the chunks is really important! \u26A0\uFE0F\n await installChunkedCode({\n actor,\n code: {\n ...rest,\n chunkHashesList: [...chunkIds, ...storedChunks]\n .sort(({orderId: orderIdA}, {orderId: orderIdB}) => orderIdA - orderIdB)\n .map(({chunkHash}) => chunkHash),\n targetCanisterId: canisterId,\n wasmModuleHash: await uint8ArraySha256(wasmModule)\n }\n });\n\n // Finally let's clear only if no mission control is provided, as the chunks might be reused in that case.\n if (postClearChunks) {\n await clearChunkStore({actor, canisterId});\n }\n};\n\nconst wasmToChunks = async ({\n wasmModule\n}: Pick<UpgradeCodeParams, 'wasmModule'>): Promise<UploadChunkParams[]> => {\n const blob = new Blob([wasmModule as Uint8Array<ArrayBuffer>]);\n\n const uploadChunks: UploadChunkParams[] = [];\n\n const chunkSize = INSTALL_MAX_CHUNK_SIZE;\n\n // Split data into chunks\n let orderId = 0;\n for (let start = 0; start < blob.size; start += chunkSize) {\n const chunk = blob.slice(start, start + chunkSize);\n uploadChunks.push({\n chunk,\n orderId,\n sha256: await blobSha256(chunk)\n });\n\n orderId++;\n }\n\n return uploadChunks;\n};\n\ninterface PrepareUpload {\n uploadChunks: UploadChunkParams[];\n storedChunks: UploadChunkResult[];\n preClearChunks: boolean;\n postClearChunks: boolean;\n}\n\n/**\n * Prepares the upload of WASM chunks by determining which chunks need to be uploaded\n * and which are already stored. Additionally, it provides flags for pre-clear and post-clear operations.\n *\n * The stored chunks are fetched from the `canisterId`.\n *\n * In the response:\n * - `preClearChunks` is set to `true` if no stored chunks matching the one we are about to upload are detected.\n * - `postClearChunks` is always set to `true` because we are using the same canister to upload chunks. In the future,\n * if this function is upgraded with an orchestrator that holds chunks for multiple canisters, it should be set to `false` for that use case.\n *\n * @param {Object} params - The input parameters.\n * @param {string} params.canisterId - The ID of the target canister.\n * @param {Object} params.actor - The actor instance for interacting with the canister.\n * @param {UploadChunkParams[]} params.wasmChunks - The WASM chunks to be uploaded, including their hashes and metadata.\n *\n * @returns {Promise<PrepareUpload>} Resolves to an object containing:\n */\nconst prepareUpload = async ({\n canisterId,\n actor,\n wasmChunks\n}: Pick<UpgradeCodeParams, 'canisterId' | 'actor'> & {\n wasmChunks: UploadChunkParams[];\n}): Promise<PrepareUpload> => {\n const stored = await storedChunksApi({\n actor,\n // We used to store the chunks, if provided, within Mission Control. However, this module\n // was recently merged with Monitoring and therefore no longer acts as an orchestrator.\n // Furthermore, note that the canister holding the chunks must live on the same subnet\n // as the canister that downloads them for the upgrade. The IC does not support this\n // process across subnets \u26A0\uFE0F.\n // See documentation: https://docs.internetcomputer.org/references/ic-interface-spec#ic-install_chunked_code\n canisterId\n });\n\n // We convert existing hash to extend with an easily comparable sha256 as hex value\n const existingStoredChunks: (Pick<UploadChunkResult, 'chunkHash'> &\n Pick<UploadChunkParams, 'sha256'>)[] = stored.map(({hash}) => ({\n chunkHash: {hash},\n sha256: uint8ArrayToHexString(hash)\n }));\n\n const {storedChunks, uploadChunks} = wasmChunks.reduce<\n Omit<PrepareUpload, 'preClearChunks' | 'postClearChunks'>\n >(\n ({uploadChunks, storedChunks}, {sha256, ...rest}) => {\n const existingStoredChunk = existingStoredChunks.find(\n ({sha256: storedSha256}) => storedSha256 === sha256\n );\n\n return {\n uploadChunks: [\n ...uploadChunks,\n ...(nonNullish(existingStoredChunk) ? [] : [{sha256, ...rest}])\n ],\n storedChunks: [\n ...storedChunks,\n ...(nonNullish(existingStoredChunk) ? [{...rest, ...existingStoredChunk}] : [])\n ]\n };\n },\n {\n uploadChunks: [],\n storedChunks: []\n }\n );\n\n return {\n uploadChunks,\n storedChunks,\n preClearChunks: stored.length > 0 && storedChunks.length === 0,\n postClearChunks: true\n };\n};\n\nasync function* batchUploadChunks({\n uploadChunks,\n limit = 12,\n ...rest\n}: Pick<UpgradeCodeParams, 'actor' | 'canisterId'> & {\n uploadChunks: UploadChunkParams[];\n limit?: number;\n}): AsyncGenerator<UploadChunkResult[], void> {\n for (let i = 0; i < uploadChunks.length; i = i + limit) {\n const batch = uploadChunks.slice(i, i + limit);\n const result = await Promise.all(\n batch.map((uploadChunkParams) =>\n uploadChunk({\n uploadChunk: uploadChunkParams,\n ...rest\n })\n )\n );\n yield result;\n }\n}\n\nconst uploadChunk = async ({\n actor,\n canisterId,\n uploadChunk: {chunk, ...rest}\n}: Pick<UpgradeCodeParams, 'actor' | 'canisterId'> & {\n uploadChunk: UploadChunkParams;\n}): Promise<UploadChunkResult> => {\n const chunkHash = await uploadChunkApi({\n actor,\n chunk: {\n canisterId,\n chunk: new Uint8Array(await chunk.arrayBuffer())\n }\n });\n\n return {\n chunkHash,\n ...rest\n };\n};\n", "import {installCode} from '../api/ic.api';\nimport type {UpgradeCodeParams} from '../types/upgrade';\n\nexport const upgradeSingleChunkCode = async ({actor, ...rest}: UpgradeCodeParams) => {\n await installCode({\n actor,\n code: rest\n });\n};\n", "import {IDL} from '@icp-sdk/core/candid';\nimport type {Principal} from '@icp-sdk/core/principal';\nimport type {SatelliteDid} from '@junobuild/ic-client/actor';\n\nexport const encoreIDLUser = (user: Principal): Uint8Array =>\n IDL.encode(\n [\n IDL.Record({\n user: IDL.Principal\n })\n ],\n [{user}]\n );\n\nexport const encodeAdminAccessKeysToIDL = (\n controllers: [Principal, SatelliteDid.AccessKey][]\n): Uint8Array =>\n IDL.encode(\n [\n IDL.Record({\n controllers: IDL.Vec(IDL.Principal)\n })\n ],\n [\n {\n controllers: controllers\n .filter(([_, {scope}]) => 'Admin' in scope)\n .map(([controller, _]) => controller)\n }\n ]\n );\n", "import {JUNO_PACKAGE_MISSION_CONTROL_ID} from '@junobuild/config';\nimport type {MissionControlParameters} from '@junobuild/ic-client/actor';\nimport {assertNonNullish, isNullish} from '@junobuild/utils';\nimport {version} from '../api/mission-control.api';\nimport {MissionControlVersionError} from '../errors/version.errors';\nimport {getJunoPackage} from './package.services';\n\n/**\n * Retrieves the version of Mission Control.\n * @param {Object} params - The parameters for Mission Control.\n * @param {MissionControlParameters} params.missionControl - The Mission Control parameters.\n * @returns {Promise<string>} A promise that resolves to the version of Mission Control.\n */\nexport const missionControlVersion = async ({\n missionControl: {missionControlId, ...rest}\n}: {\n missionControl: MissionControlParameters;\n}): Promise<string> => {\n assertNonNullish(\n missionControlId,\n 'A Mission Control ID must be provided to request its version.'\n );\n\n const pkg = await getJunoPackage({\n moduleId: missionControlId,\n ...rest\n });\n\n // For backwards compatibility with legacy. Function version() was deprecated in Mission Control > v0.0.14\n if (isNullish(pkg)) {\n return await version({missionControl: {missionControlId, ...rest}});\n }\n\n const {name, version: missionControlVersion} = pkg;\n\n if (name === JUNO_PACKAGE_MISSION_CONTROL_ID) {\n return missionControlVersion;\n }\n\n throw new MissionControlVersionError();\n};\n", "import type {Principal} from '@icp-sdk/core/principal';\nimport {type JunoPackage, JunoPackageSchema} from '@junobuild/config';\nimport type {ActorParameters} from '@junobuild/ic-client/actor';\nimport {isNullish} from '@junobuild/utils';\nimport * as z from 'zod';\nimport {canisterMetadata} from '../api/ic.api';\n\n/**\n * Parameters required to retrieve a `juno:package` metadata section.\n *\n * @typedef {Object} GetJunoPackageParams\n * @property {Principal | string} moduleId - The ID of the canister module (as a Principal or string).\n * @property {ActorParameters} [ActorParameters] - Additional actor parameters for making the canister call.\n */\nexport type GetJunoPackageParams = {moduleId: Principal | string} & ActorParameters;\n\n/**\n * Get the `juno:package` metadata from the public custom section of a given module.\n *\n * @param {Object} params - The parameters to fetch the metadata.\n * @param {Principal | string} params.moduleId - The canister ID (as a `Principal` or string) from which to retrieve the metadata.\n * @param {ActorParameters} params - Additional actor parameters required for the call.\n *\n * @returns {Promise<JunoPackage | undefined>} A promise that resolves to the parsed `JunoPackage` metadata, or `undefined` if not found.\n *\n * @throws {ZodError} If the metadata exists but does not conform to the expected `JunoPackage` schema.\n */\nexport const getJunoPackage = async ({\n moduleId,\n ...rest\n}: GetJunoPackageParams): Promise<JunoPackage | undefined> => {\n const status = await canisterMetadata({...rest, canisterId: moduleId, path: 'juno:package'});\n\n if (isNullish(status)) {\n return undefined;\n }\n\n if (typeof status !== 'string') {\n throw new Error('Unexpected metadata type to parse public custom section juno:package');\n }\n\n // https://stackoverflow.com/a/75881231/5404186\n // https://github.com/colinhacks/zod/discussions/2215#discussioncomment-5356286\n const createPackageFromJson = (content: string): JunoPackage =>\n z\n .string()\n // eslint-disable-next-line local-rules/prefer-object-params\n .transform((str, ctx) => {\n try {\n return JSON.parse(str);\n } catch (_err: unknown) {\n ctx.addIssue({\n code: 'custom',\n message: 'Invalid JSON'\n });\n return z.never;\n }\n })\n .pipe(JunoPackageSchema)\n .parse(content);\n\n return createPackageFromJson(status);\n};\n\n/**\n * Retrieves only the `version` field from the `juno:package` metadata.\n *\n * @param {GetJunoPackageParams} params - The parameters to fetch the package version.\n *\n * @returns {Promise<string | undefined>} A promise that resolves to the version string or `undefined` if not found.\n *\n * @throws {ZodError} If the metadata exists but does not conform to the expected `JunoPackage` schema.\n */\nexport const getJunoPackageVersion = async (\n params: GetJunoPackageParams\n): Promise<JunoPackage['version'] | undefined> => {\n const pkg = await getJunoPackage(params);\n return pkg?.version;\n};\n\n/**\n * Retrieves the `dependencies` field from the `juno:package` metadata.\n *\n * @param {GetJunoPackageParams} params - The parameters to fetch the package metadata.\n *\n * @returns {Promise<JunoPackage['dependencies'] | undefined>} A promise that resolves to the dependencies object or `undefined` if not found.\n *\n * @throws {ZodError} If the metadata exists but does not conform to the expected `JunoPackage` schema.\n */\nexport const getJunoPackageDependencies = async (\n params: GetJunoPackageParams\n): Promise<JunoPackage['dependencies'] | undefined> => {\n const pkg = await getJunoPackage(params);\n return pkg?.dependencies;\n};\n", "import type {ActorParameters} from '@junobuild/ic-client/actor';\nimport {upgrade} from '../handlers/upgrade.handlers';\nimport type {UpgradeCodeParams} from '../types/upgrade';\n\n/**\n * Upgrades a module with the provided WASM code and arguments. This generic is notably useful for Juno Docker.\n *\n * @param {Object} params - Parameters for upgrading the module.\n * @param {ActorParameters} params.actor - The actor parameters associated with the module.\n * @param {Principal} params.canisterId - The ID of the canister being upgraded.\n * @param {Principal} [params.missionControlId] - Optional. An ID to store and reuse WASM chunks across installations.\n * @param {Uint8Array} params.wasmModule - The WASM code to be installed during the upgrade.\n * @param {Uint8Array} params.arg - The initialization argument for the module upgrade.\n * @param {canister_install_mode} params.mode - The installation mode, e.g., `upgrade` or `reinstall`.\n * @param {boolean} [params.preClearChunks] - Optional. Forces clearing existing chunks before uploading a chunked WASM module. Recommended for WASM modules larger than 2MB.\n * @param {function} [params.onProgress] - Optional. Callback function to track progress during the upgrade process.\n * @param {boolean} [params.reset=false] - Optional. Specifies whether to reset the module (reinstall) instead of performing an upgrade. Defaults to `false`.\n * @throws {Error} Will throw an error if the parameters are invalid or if the upgrade process fails.\n * @returns {Promise<void>} Resolves when the upgrade process is complete.\n */\nexport const upgradeModule = async (\n params: {\n actor: ActorParameters;\n reset?: boolean;\n } & UpgradeCodeParams\n): Promise<void> => {\n await upgrade(params);\n};\n", "import type {Principal} from '@icp-sdk/core/principal';\nimport {\n type OrbiterDid,\n type OrbiterParameters,\n getDeprecatedOrbiterVersionActor,\n getOrbiterActor\n} from '@junobuild/ic-client/actor';\n\n/**\n * @deprecated - Replaced in Orbiter > v0.0.8 with public custom section juno:package\n */\nexport const version = async ({orbiter}: {orbiter: OrbiterParameters}): Promise<string> => {\n const {version} = await getDeprecatedOrbiterVersionActor(orbiter);\n return version();\n};\n\nexport const listControllers = async ({\n orbiter,\n certified\n}: {\n orbiter: OrbiterParameters;\n certified?: boolean;\n}): Promise<[Principal, OrbiterDid.AccessKey][]> => {\n const {list_controllers} = await getOrbiterActor({...orbiter, certified});\n return list_controllers();\n};\n\nexport const setControllers = async ({\n args,\n orbiter\n}: {\n args: OrbiterDid.SetControllersArgs;\n orbiter: OrbiterParameters;\n}): Promise<[Principal, OrbiterDid.AccessKey][]> => {\n const {set_controllers} = await getOrbiterActor(orbiter);\n return set_controllers(args);\n};\n\nexport const memorySize = async ({\n orbiter\n}: {\n orbiter: OrbiterParameters;\n}): Promise<OrbiterDid.MemorySize> => {\n const {memory_size} = await getOrbiterActor(orbiter);\n return memory_size();\n};\n", "import type {Principal} from '@icp-sdk/core/principal';\nimport type {MissionControlDid, OrbiterDid, OrbiterParameters} from '@junobuild/ic-client/actor';\nimport {listControllers, setControllers} from '../api/orbiter.api';\n\n/**\n * Lists the controllers of the Orbiter.\n * @param {Object} params - The parameters for listing the controllers.\n * @param {OrbiterParameters} params.orbiter - The Orbiter parameters.\n * @returns {Promise<[Principal, Controller][]>} A promise that resolves to a list of controllers.\n */\nexport const listOrbiterControllers = (params: {\n orbiter: OrbiterParameters;\n}): Promise<[Principal, MissionControlDid.AccessKey][]> => listControllers(params);\n\n/**\n * Sets the controllers of an orbiter.\n * @param {Object} params - The parameters for setting the controllers.\n * @param {SatelliteParameters} params.orbiter - The orbiter parameters.\n * @param {SetControllersArgs} params.args - The arguments for setting the controllers.\n * @returns {Promise<[Principal, Controller][]>} A promise that resolves to a list of controllers.\n */\nexport const setOrbiterControllers = (params: {\n orbiter: OrbiterParameters;\n args: OrbiterDid.SetControllersArgs;\n}): Promise<[Principal, OrbiterDid.AccessKey][]> => setControllers(params);\n", "import type {OrbiterDid, OrbiterParameters} from '@junobuild/ic-client/actor';\nimport {memorySize} from '../api/orbiter.api';\n\n/**\n * Retrieves the stable and heap memory size of the Orbiter.\n * @param {Object} params - The parameters for the Orbiter.\n * @param {OrbiterParameters} params.orbiter - The Orbiter parameters.\n * @returns {Promise<MemorySize>} A promise that resolves to the memory size of the Orbiter.\n */\nexport const orbiterMemorySize = (params: {\n orbiter: OrbiterParameters;\n}): Promise<OrbiterDid.MemorySize> => memorySize(params);\n", "import type {OrbiterParameters} from '@junobuild/ic-client/actor';\nimport {toPrincipal} from '@junobuild/ic-client/utils';\nimport {listControllers} from '../api/orbiter.api';\nimport {INSTALL_MODE_RESET, INSTALL_MODE_UPGRADE} from '../constants/upgrade.constants';\nimport {upgrade} from '../handlers/upgrade.handlers';\nimport type {UpgradeCodeParams} from '../types/upgrade';\nimport {encodeAdminAccessKeysToIDL} from '../utils/idl.utils';\n\n/**\n * Upgrades the Orbiter with the provided WASM module.\n * @param {Object} params - The parameters for upgrading the Orbiter.\n * @param {OrbiterParameters} params.orbiter - The Orbiter parameters, including the actor and orbiter ID.\n * @param {Uint8Array} params.wasmModule - The WASM module to be installed during the upgrade.\n * @param {boolean} [params.reset=false] - Optional. Indicates whether to reset the Orbiter (reinstall) instead of performing an u