diff --git a/CHANGELOG.md b/CHANGELOG.md index 27bdf75d..6baa748c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +# 2024.xx.yy-hhmmZ + +# Breaking changes + +- Inherits canister installation code arguments from Candid. + # 2024.11.21-1600Z ## Overview diff --git a/packages/ic-management/README.md b/packages/ic-management/README.md index 6670b214..92fa8e07 100644 --- a/packages/ic-management/README.md +++ b/packages/ic-management/README.md @@ -54,7 +54,7 @@ const { status, memory_size, ...rest } = await canisterStatus(YOUR_CANISTER_ID); ### :factory: ICManagementCanister -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L39) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L38) #### Methods @@ -84,7 +84,7 @@ const { status, memory_size, ...rest } = await canisterStatus(YOUR_CANISTER_ID); | -------- | ---------------------------------------------------------------- | | `create` | `(options: ICManagementCanisterOptions) => ICManagementCanister` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L44) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L43) ##### :gear: createCanister @@ -94,7 +94,7 @@ Create a new canister | ---------------- | ------------------------------------------------------------------------------------- | | `createCanister` | `({ settings, senderCanisterVersion, }?: CreateCanisterParams) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L84) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L83) ##### :gear: updateSettings @@ -104,17 +104,17 @@ Update canister settings | ---------------- | ------------------------------------------------------------------------------------------- | | `updateSettings` | `({ canisterId, senderCanisterVersion, settings, }: UpdateSettingsParams) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L107) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L106) ##### :gear: installCode Install code to a canister -| Method | Type | -| ------------- | ----------------------------------------------------------------------------------------------------- | -| `installCode` | `({ mode, canisterId, wasmModule, arg, senderCanisterVersion, }: InstallCodeParams) => Promise` | +| Method | Type | +| ------------- | -------------------------------------------------------------------------------------------------- | +| `installCode` | `({ canisterId, wasmModule, senderCanisterVersion, ...rest }: InstallCodeParams) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L132) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L131) ##### :gear: uploadChunk @@ -129,7 +129,7 @@ Parameters: - `params.canisterId`: The canister in which the chunks will be stored. - `params.chunk`: A chunk of Wasm module. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L160) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L157) ##### :gear: clearChunkStore @@ -143,7 +143,7 @@ Parameters: - `params.canisterId`: The canister in which the chunks are stored. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L180) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L177) ##### :gear: storedChunks @@ -157,15 +157,15 @@ Parameters: - `params.canisterId`: The canister in which the chunks are stored. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L199) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L196) ##### :gear: installChunkedCode Installs code that had previously been uploaded in chunks. -| Method | Type | -| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `installChunkedCode` | `({ mode, arg, senderCanisterVersion, chunkHashesList, targetCanisterId, storeCanisterId, wasmModuleHash, }: InstallChunkedCodeParams) => Promise` | +| Method | Type | +| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- | +| `installChunkedCode` | `({ senderCanisterVersion, chunkHashesList, targetCanisterId, storeCanisterId, wasmModuleHash, ...rest }: InstallChunkedCodeParams) => Promise` | Parameters: @@ -177,7 +177,7 @@ Parameters: - `params.storeCanisterId`: Specifies the canister in whose chunk storage the chunks are stored (this parameter defaults to target_canister if not specified). - `params.wasmModuleHash`: The Wasm module hash as hex string. Used to check that the SHA-256 hash of wasm_module is equal to the wasm_module_hash parameter and can calls install_code with parameters. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L224) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L221) ##### :gear: uninstallCode @@ -187,7 +187,7 @@ Uninstall code from a canister | --------------- | -------------------------------------------------------------------------------- | | `uninstallCode` | `({ canisterId, senderCanisterVersion, }: UninstallCodeParams) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L257) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L252) ##### :gear: startCanister @@ -197,7 +197,7 @@ Start a canister | --------------- | ------------------------------------------ | | `startCanister` | `(canisterId: Principal) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L275) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L270) ##### :gear: stopCanister @@ -207,7 +207,7 @@ Stop a canister | -------------- | ------------------------------------------ | | `stopCanister` | `(canisterId: Principal) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L287) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L282) ##### :gear: canisterStatus @@ -217,7 +217,7 @@ Get canister details (memory size, status, etc.) | ---------------- | ------------------------------------------------------------ | | `canisterStatus` | `(canisterId: Principal) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L298) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L293) ##### :gear: deleteCanister @@ -227,7 +227,7 @@ Deletes a canister | ---------------- | ------------------------------------------ | | `deleteCanister` | `(canisterId: Principal) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L312) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L307) ##### :gear: provisionalCreateCanisterWithCycles @@ -237,7 +237,7 @@ Creates a canister. Only available on development instances. | ------------------------------------- | ------------------------------------------------------------------------------------------------------- | | `provisionalCreateCanisterWithCycles` | `({ settings, amount, canisterId, }?: ProvisionalCreateCanisterWithCyclesParams) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L327) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L322) ##### :gear: fetchCanisterLogs @@ -247,7 +247,7 @@ Given a canister ID as input, this method returns a vector of logs of that canis | ------------------- | ---------------------------------------------------------------- | | `fetchCanisterLogs` | `(canisterId: Principal) => Promise` | -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L350) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L345) ##### :gear: takeCanisterSnapshot @@ -265,7 +265,7 @@ Parameters: Can be provided as a `string` or a `Uint8Array`. If not provided, a new snapshot will be created. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L376) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L371) ##### :gear: listCanisterSnapshots @@ -280,7 +280,7 @@ Parameters: - `params`: - Parameters for the listing operation. - `params.canisterId`: - The ID of the canister for which snapshots will be listed. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L405) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L400) ##### :gear: loadCanisterSnapshot @@ -297,7 +297,7 @@ Parameters: - `params.snapshotId`: - The ID of the snapshot to load. - `params.senderCanisterVersion`: - The optional sender canister version. If provided, its value must be equal to ic0.canister_version. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L431) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L426) ##### :gear: deleteCanisterSnapshot @@ -313,7 +313,7 @@ Parameters: - `params.canisterId`: - The ID of the canister for which the snapshot will be deleted. - `params.snapshotId`: - The ID of the snapshot to delete. -[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L462) +[:link: Source](https://github.com/dfinity/ic-js/tree/main/packages/ic-management/src/ic-management.canister.ts#L457) diff --git a/packages/ic-management/src/ic-management.canister.spec.ts b/packages/ic-management/src/ic-management.canister.spec.ts index c2995d57..9e7507bc 100644 --- a/packages/ic-management/src/ic-management.canister.spec.ts +++ b/packages/ic-management/src/ic-management.canister.spec.ts @@ -4,6 +4,7 @@ import { toNullable } from "@dfinity/utils"; import { mock } from "jest-mock-extended"; import type { _SERVICE as IcManagementService, + canister_install_mode, chunk_hash, list_canister_snapshots_result, take_canister_snapshot_result, @@ -21,10 +22,8 @@ import type { InstallCodeParams, } from "./types/ic-management.params"; import { - InstallMode, LogVisibility, UnsupportedLogVisibility, - toInstallMode, type ClearChunkStoreParams, type InstallChunkedCodeParams, type StoredChunksParams, @@ -37,6 +36,52 @@ import { decodeSnapshotId } from "./utils/ic-management.utils"; describe("ICManagementCanister", () => { const mockAgent: HttpAgent = mock(); + const mockInstallCodeModes: canister_install_mode[] = [ + { install: null }, + { reinstall: null }, + { upgrade: [] }, + { + upgrade: [ + { + wasm_memory_persistence: [], + skip_pre_upgrade: [], + }, + ], + }, + { + upgrade: [ + { + wasm_memory_persistence: [{ keep: null }], + skip_pre_upgrade: [], + }, + ], + }, + { + upgrade: [ + { + wasm_memory_persistence: [{ replace: null }], + skip_pre_upgrade: [], + }, + ], + }, + { + upgrade: [ + { + wasm_memory_persistence: [], + skip_pre_upgrade: [true], + }, + ], + }, + { + upgrade: [ + { + wasm_memory_persistence: [{ replace: null }], + skip_pre_upgrade: [false], + }, + ], + }, + ]; + const createICManagement = async (service: IcManagementService) => { return ICManagementCanister.create({ agent: mockAgent, @@ -210,7 +255,7 @@ describe("ICManagementCanister", () => { }); describe("installCode", () => { - it.each([InstallMode.Install, InstallMode.Reinstall, InstallMode.Upgrade])( + it.each(mockInstallCodeModes)( "calls install_code with mode %s", async (mode) => { const params: InstallCodeParams = { @@ -228,7 +273,7 @@ describe("ICManagementCanister", () => { expect(service.install_code).toHaveBeenCalledWith({ wasm_module: params.wasmModule, - mode: toInstallMode(params.mode), + mode: params.mode, canister_id: params.canisterId, arg: params.arg, sender_canister_version: [], @@ -239,7 +284,7 @@ describe("ICManagementCanister", () => { it("throws Error", async () => { const params: InstallCodeParams = { wasmModule: new Uint8Array([1, 2, 3]), - mode: InstallMode.Install, + mode: { install: null }, arg: new Uint8Array(), canisterId: mockCanisterId, }; @@ -581,7 +626,7 @@ describe("ICManagementCanister", () => { chunkHashesList: [{ hash: [1, 2, 3] }, { hash: [4, 5, 6] }], }; - it.each([InstallMode.Install, InstallMode.Reinstall, InstallMode.Upgrade])( + it.each(mockInstallCodeModes)( "calls install_chunked_code with mode %s", async (mode) => { const params: InstallChunkedCodeParams = { @@ -598,7 +643,7 @@ describe("ICManagementCanister", () => { expect(service.install_chunked_code).toHaveBeenCalledWith({ wasm_module_hash: params.wasmModuleHash, - mode: toInstallMode(params.mode), + mode: params.mode, target_canister: params.targetCanisterId, store_canister: toNullable(), arg: params.arg, @@ -611,7 +656,7 @@ describe("ICManagementCanister", () => { it("should accept sha256 as hex string parameter", async () => { const params: InstallChunkedCodeParams = { ...installParams, - mode: InstallMode.Upgrade, + mode: { upgrade: [] }, wasmModuleHash: sha256HashHex, }; const service = mock(); @@ -623,7 +668,7 @@ describe("ICManagementCanister", () => { expect(service.install_chunked_code).toHaveBeenCalledWith({ wasm_module_hash: sha256HashUint8Array, - mode: toInstallMode(params.mode), + mode: params.mode, target_canister: params.targetCanisterId, store_canister: toNullable(), arg: params.arg, @@ -635,7 +680,7 @@ describe("ICManagementCanister", () => { it("should optionally target a particular store canister", async () => { const params: InstallChunkedCodeParams = { ...installParams, - mode: InstallMode.Upgrade, + mode: { upgrade: [] }, wasmModuleHash: sha256HashHex, storeCanisterId: mockCanisterId, }; @@ -648,7 +693,7 @@ describe("ICManagementCanister", () => { expect(service.install_chunked_code).toHaveBeenCalledWith({ wasm_module_hash: sha256HashUint8Array, - mode: toInstallMode(params.mode), + mode: { upgrade: [] }, target_canister: params.targetCanisterId, store_canister: toNullable(mockCanisterId), arg: params.arg, @@ -660,7 +705,7 @@ describe("ICManagementCanister", () => { it("throws Error", async () => { const params: InstallChunkedCodeParams = { ...installParams, - mode: InstallMode.Install, + mode: { install: null }, wasmModuleHash: sha256HashUint8Array, }; const error = new Error("Test"); diff --git a/packages/ic-management/src/ic-management.canister.ts b/packages/ic-management/src/ic-management.canister.ts index aa974752..5dfc3cdd 100644 --- a/packages/ic-management/src/ic-management.canister.ts +++ b/packages/ic-management/src/ic-management.canister.ts @@ -18,7 +18,6 @@ import { idlFactory } from "../candid/ic-management.idl"; import type { ICManagementCanisterOptions } from "./types/canister.options"; import { toCanisterSettings, - toInstallMode, type ClearChunkStoreParams, type CreateCanisterParams, type InstallChunkedCodeParams, @@ -122,7 +121,7 @@ export class ICManagementCanister { * Install code to a canister * * @param {Object} params - * @param {InstallMode} params.mode + * @param {canister_install_mode} params.mode * @param {Principal} params.canisterId * @param {Uint8Array} params.wasmModule * @param {Uint8Array} params.arg @@ -130,19 +129,17 @@ export class ICManagementCanister { * @returns {Promise} */ installCode = ({ - mode, canisterId, wasmModule, - arg, senderCanisterVersion, + ...rest }: InstallCodeParams): Promise => { const { install_code } = this.service; return install_code({ - mode: toInstallMode(mode), + ...rest, canister_id: canisterId, wasm_module: wasmModule, - arg, sender_canister_version: toNullable(senderCanisterVersion), }); }; @@ -212,7 +209,7 @@ export class ICManagementCanister { * @link https://internetcomputer.org/docs/current/references/ic-interface-spec/#ic-install_chunked_code * * @param {InstallChunkedCodeParams} params - * @param {InstallMode} params.mode Installation, re-installation or upgrade. + * @param {canister_install_mode} params.mode Installation, re-installation or upgrade. * @param {Uint8Array} params.arg The arguments of the canister. * @param {Uint8Array | undefined} params.senderCanisterVersion The optional sender_canister_version parameter can contain the caller's canister version. * @param {Array} params.chunkHashesList The list of chunks of the Wasm module to install. @@ -222,21 +219,19 @@ export class ICManagementCanister { * @returns {Promise} */ installChunkedCode = async ({ - mode, - arg, senderCanisterVersion, chunkHashesList, targetCanisterId, storeCanisterId, wasmModuleHash, + ...rest }: InstallChunkedCodeParams): Promise => { const { install_chunked_code } = this.service; await install_chunked_code({ - mode: toInstallMode(mode), + ...rest, target_canister: targetCanisterId, store_canister: toNullable(storeCanisterId), - arg, sender_canister_version: toNullable(senderCanisterVersion), chunk_hashes_list: chunkHashesList, wasm_module_hash: diff --git a/packages/ic-management/src/index.ts b/packages/ic-management/src/index.ts index 8980d299..4a6b5dec 100644 --- a/packages/ic-management/src/index.ts +++ b/packages/ic-management/src/index.ts @@ -1,4 +1,5 @@ export type { + canister_install_mode, canister_log_record, canister_status_result, chunk_hash, diff --git a/packages/ic-management/src/types/ic-management.params.ts b/packages/ic-management/src/types/ic-management.params.ts index cf5726f3..20b61688 100644 --- a/packages/ic-management/src/types/ic-management.params.ts +++ b/packages/ic-management/src/types/ic-management.params.ts @@ -67,30 +67,8 @@ export interface UpdateSettingsParams { settings: CanisterSettings; } -export enum InstallMode { - Install, - Reinstall, - Upgrade, -} - -export const toInstallMode = ( - installMode: InstallMode, -): canister_install_mode => { - switch (installMode) { - case InstallMode.Install: - return { install: null }; - case InstallMode.Reinstall: - return { reinstall: null }; - case InstallMode.Upgrade: - // TODO: Support Upgrade mode skipping pre-upgrade and wasm_memory_persistence - // `upgrade` can also have `[{ skip_pre_upgrade: [] | [boolean] }]` - // or wasm_memory_persistence : opt variant { keep; replace; }; - return { upgrade: [] }; - } -}; - export interface InstallCodeParams { - mode: InstallMode; + mode: canister_install_mode; canisterId: Principal; wasmModule: Uint8Array; arg: Uint8Array;