From cce13b6a874e108e9f6b45f498e4dbbb79e71623 Mon Sep 17 00:00:00 2001 From: NathanosDev Date: Thu, 25 Jan 2024 01:16:32 +0100 Subject: [PATCH] refactor: use auto-generated idl for management canister --- .../src/candid/management-canister/index.d.ts | 268 +++++++++++++ .../src/candid/management-canister/index.js | 364 ++++++++++++++++++ packages/pic/src/management-canister.ts | 75 ---- packages/pic/src/pocket-ic-types.ts | 2 + packages/pic/src/pocket-ic.ts | 106 ++--- packages/pic/src/util/candid.ts | 4 + packages/pic/tsconfig.json | 1 + 7 files changed, 694 insertions(+), 126 deletions(-) create mode 100644 packages/pic/src/candid/management-canister/index.d.ts create mode 100644 packages/pic/src/candid/management-canister/index.js delete mode 100644 packages/pic/src/management-canister.ts diff --git a/packages/pic/src/candid/management-canister/index.d.ts b/packages/pic/src/candid/management-canister/index.d.ts new file mode 100644 index 0000000..160c9ee --- /dev/null +++ b/packages/pic/src/candid/management-canister/index.d.ts @@ -0,0 +1,268 @@ +import type { ActorMethod } from '@dfinity/agent'; +import type { Principal } from '@dfinity/principal'; +import type { IDL } from '@dfinity/candid'; + +export const idlFactory: IDL.InterfaceFactory; + +export type bitcoin_address = string; +export type bitcoin_network = { mainnet: null } | { testnet: null }; +export type block_hash = Uint8Array | number[]; +export type canister_id = Principal; +export interface canister_settings { + freezing_threshold: [] | [bigint]; + controllers: [] | [Array]; + reserved_cycles_limit: [] | [bigint]; + memory_allocation: [] | [bigint]; + compute_allocation: [] | [bigint]; +} +export interface change { + timestamp_nanos: bigint; + canister_version: bigint; + origin: change_origin; + details: change_details; +} +export type change_details = + | { + creation: { controllers: Array }; + } + | { + code_deployment: { + mode: { reinstall: null } | { upgrade: null } | { install: null }; + module_hash: Uint8Array | number[]; + }; + } + | { controllers_change: { controllers: Array } } + | { code_uninstall: null }; +export type change_origin = + | { from_user: { user_id: Principal } } + | { + from_canister: { + canister_version: [] | [bigint]; + canister_id: Principal; + }; + }; +export type chunk_hash = Uint8Array | number[]; +export interface definite_canister_settings { + freezing_threshold: bigint; + controllers: Array; + reserved_cycles_limit: bigint; + memory_allocation: bigint; + compute_allocation: bigint; +} +export type ecdsa_curve = { secp256k1: null }; +export interface get_balance_request { + network: bitcoin_network; + address: bitcoin_address; + min_confirmations: [] | [number]; +} +export interface get_current_fee_percentiles_request { + network: bitcoin_network; +} +export interface get_utxos_request { + network: bitcoin_network; + filter: + | [] + | [{ page: Uint8Array | number[] } | { min_confirmations: number }]; + address: bitcoin_address; +} +export interface get_utxos_response { + next_page: [] | [Uint8Array | number[]]; + tip_height: number; + tip_block_hash: block_hash; + utxos: Array; +} +export interface http_header { + value: string; + name: string; +} +export interface http_response { + status: bigint; + body: Uint8Array | number[]; + headers: Array; +} +export type millisatoshi_per_byte = bigint; +export interface node_metrics { + num_block_failures_total: bigint; + node_id: Principal; + num_blocks_total: bigint; +} +export interface outpoint { + txid: Uint8Array | number[]; + vout: number; +} +export type satoshi = bigint; +export interface send_transaction_request { + transaction: Uint8Array | number[]; + network: bitcoin_network; +} +export interface utxo { + height: number; + value: satoshi; + outpoint: outpoint; +} +export type wasm_module = Uint8Array | number[]; +export interface _SERVICE { + bitcoin_get_balance: ActorMethod<[get_balance_request], satoshi>; + bitcoin_get_balance_query: ActorMethod<[get_balance_request], satoshi>; + bitcoin_get_current_fee_percentiles: ActorMethod< + [get_current_fee_percentiles_request], + BigUint64Array | bigint[] + >; + bitcoin_get_utxos: ActorMethod<[get_utxos_request], get_utxos_response>; + bitcoin_get_utxos_query: ActorMethod<[get_utxos_request], get_utxos_response>; + bitcoin_send_transaction: ActorMethod<[send_transaction_request], undefined>; + canister_info: ActorMethod< + [{ canister_id: canister_id; num_requested_changes: [] | [bigint] }], + { + controllers: Array; + module_hash: [] | [Uint8Array | number[]]; + recent_changes: Array; + total_num_changes: bigint; + } + >; + canister_status: ActorMethod< + [{ canister_id: canister_id }], + { + status: { stopped: null } | { stopping: null } | { running: null }; + memory_size: bigint; + cycles: bigint; + settings: definite_canister_settings; + idle_cycles_burned_per_day: bigint; + module_hash: [] | [Uint8Array | number[]]; + reserved_cycles: bigint; + } + >; + clear_chunk_store: ActorMethod<[{ canister_id: canister_id }], undefined>; + create_canister: ActorMethod< + [ + { + settings: [] | [canister_settings]; + sender_canister_version: [] | [bigint]; + }, + ], + { canister_id: canister_id } + >; + delete_canister: ActorMethod<[{ canister_id: canister_id }], undefined>; + deposit_cycles: ActorMethod<[{ canister_id: canister_id }], undefined>; + ecdsa_public_key: ActorMethod< + [ + { + key_id: { name: string; curve: ecdsa_curve }; + canister_id: [] | [canister_id]; + derivation_path: Array; + }, + ], + { + public_key: Uint8Array | number[]; + chain_code: Uint8Array | number[]; + } + >; + http_request: ActorMethod< + [ + { + url: string; + method: { get: null } | { head: null } | { post: null }; + max_response_bytes: [] | [bigint]; + body: [] | [Uint8Array | number[]]; + transform: + | [] + | [ + { + function: [Principal, string]; + context: Uint8Array | number[]; + }, + ]; + headers: Array; + }, + ], + http_response + >; + install_chunked_code: ActorMethod< + [ + { + arg: Uint8Array | number[]; + wasm_module_hash: Uint8Array | number[]; + mode: + | { reinstall: null } + | { upgrade: [] | [{ skip_pre_upgrade: [] | [boolean] }] } + | { install: null }; + chunk_hashes_list: Array; + target_canister: canister_id; + sender_canister_version: [] | [bigint]; + storage_canister: [] | [canister_id]; + }, + ], + undefined + >; + install_code: ActorMethod< + [ + { + arg: Uint8Array | number[]; + wasm_module: wasm_module; + mode: + | { reinstall: null } + | { upgrade: [] | [{ skip_pre_upgrade: [] | [boolean] }] } + | { install: null }; + canister_id: canister_id; + sender_canister_version: [] | [bigint]; + }, + ], + undefined + >; + node_metrics_history: ActorMethod< + [{ start_at_timestamp_nanos: bigint; subnet_id: Principal }], + Array<{ timestamp_nanos: bigint; node_metrics: Array }> + >; + provisional_create_canister_with_cycles: ActorMethod< + [ + { + settings: [] | [canister_settings]; + specified_id: [] | [canister_id]; + amount: [] | [bigint]; + sender_canister_version: [] | [bigint]; + }, + ], + { canister_id: canister_id } + >; + provisional_top_up_canister: ActorMethod< + [{ canister_id: canister_id; amount: bigint }], + undefined + >; + raw_rand: ActorMethod<[], Uint8Array | number[]>; + sign_with_ecdsa: ActorMethod< + [ + { + key_id: { name: string; curve: ecdsa_curve }; + derivation_path: Array; + message_hash: Uint8Array | number[]; + }, + ], + { signature: Uint8Array | number[] } + >; + start_canister: ActorMethod<[{ canister_id: canister_id }], undefined>; + stop_canister: ActorMethod<[{ canister_id: canister_id }], undefined>; + stored_chunks: ActorMethod<[{ canister_id: canister_id }], Array>; + uninstall_code: ActorMethod< + [ + { + canister_id: canister_id; + sender_canister_version: [] | [bigint]; + }, + ], + undefined + >; + update_settings: ActorMethod< + [ + { + canister_id: Principal; + settings: canister_settings; + sender_canister_version: [] | [bigint]; + }, + ], + undefined + >; + upload_chunk: ActorMethod< + [{ chunk: Uint8Array | number[]; canister_id: Principal }], + chunk_hash + >; +} diff --git a/packages/pic/src/candid/management-canister/index.js b/packages/pic/src/candid/management-canister/index.js new file mode 100644 index 0000000..656182f --- /dev/null +++ b/packages/pic/src/candid/management-canister/index.js @@ -0,0 +1,364 @@ +export const idlFactory = ({ IDL }) => { + const bitcoin_network = IDL.Variant({ + mainnet: IDL.Null, + testnet: IDL.Null, + }); + const bitcoin_address = IDL.Text; + const get_balance_request = IDL.Record({ + network: bitcoin_network, + address: bitcoin_address, + min_confirmations: IDL.Opt(IDL.Nat32), + }); + const satoshi = IDL.Nat64; + const get_current_fee_percentiles_request = IDL.Record({ + network: bitcoin_network, + }); + const millisatoshi_per_byte = IDL.Nat64; + const get_utxos_request = IDL.Record({ + network: bitcoin_network, + filter: IDL.Opt( + IDL.Variant({ + page: IDL.Vec(IDL.Nat8), + min_confirmations: IDL.Nat32, + }), + ), + address: bitcoin_address, + }); + const block_hash = IDL.Vec(IDL.Nat8); + const outpoint = IDL.Record({ + txid: IDL.Vec(IDL.Nat8), + vout: IDL.Nat32, + }); + const utxo = IDL.Record({ + height: IDL.Nat32, + value: satoshi, + outpoint: outpoint, + }); + const get_utxos_response = IDL.Record({ + next_page: IDL.Opt(IDL.Vec(IDL.Nat8)), + tip_height: IDL.Nat32, + tip_block_hash: block_hash, + utxos: IDL.Vec(utxo), + }); + const send_transaction_request = IDL.Record({ + transaction: IDL.Vec(IDL.Nat8), + network: bitcoin_network, + }); + const canister_id = IDL.Principal; + const change_origin = IDL.Variant({ + from_user: IDL.Record({ user_id: IDL.Principal }), + from_canister: IDL.Record({ + canister_version: IDL.Opt(IDL.Nat64), + canister_id: IDL.Principal, + }), + }); + const change_details = IDL.Variant({ + creation: IDL.Record({ controllers: IDL.Vec(IDL.Principal) }), + code_deployment: IDL.Record({ + mode: IDL.Variant({ + reinstall: IDL.Null, + upgrade: IDL.Null, + install: IDL.Null, + }), + module_hash: IDL.Vec(IDL.Nat8), + }), + controllers_change: IDL.Record({ + controllers: IDL.Vec(IDL.Principal), + }), + code_uninstall: IDL.Null, + }); + const change = IDL.Record({ + timestamp_nanos: IDL.Nat64, + canister_version: IDL.Nat64, + origin: change_origin, + details: change_details, + }); + const definite_canister_settings = IDL.Record({ + freezing_threshold: IDL.Nat, + controllers: IDL.Vec(IDL.Principal), + reserved_cycles_limit: IDL.Nat, + memory_allocation: IDL.Nat, + compute_allocation: IDL.Nat, + }); + const canister_settings = IDL.Record({ + freezing_threshold: IDL.Opt(IDL.Nat), + controllers: IDL.Opt(IDL.Vec(IDL.Principal)), + reserved_cycles_limit: IDL.Opt(IDL.Nat), + memory_allocation: IDL.Opt(IDL.Nat), + compute_allocation: IDL.Opt(IDL.Nat), + }); + const ecdsa_curve = IDL.Variant({ secp256k1: IDL.Null }); + const http_header = IDL.Record({ value: IDL.Text, name: IDL.Text }); + const http_response = IDL.Record({ + status: IDL.Nat, + body: IDL.Vec(IDL.Nat8), + headers: IDL.Vec(http_header), + }); + const chunk_hash = IDL.Vec(IDL.Nat8); + const wasm_module = IDL.Vec(IDL.Nat8); + const node_metrics = IDL.Record({ + num_block_failures_total: IDL.Nat64, + node_id: IDL.Principal, + num_blocks_total: IDL.Nat64, + }); + return IDL.Service({ + bitcoin_get_balance: IDL.Func([get_balance_request], [satoshi], []), + bitcoin_get_balance_query: IDL.Func( + [get_balance_request], + [satoshi], + ['query'], + ), + bitcoin_get_current_fee_percentiles: IDL.Func( + [get_current_fee_percentiles_request], + [IDL.Vec(millisatoshi_per_byte)], + [], + ), + bitcoin_get_utxos: IDL.Func([get_utxos_request], [get_utxos_response], []), + bitcoin_get_utxos_query: IDL.Func( + [get_utxos_request], + [get_utxos_response], + ['query'], + ), + bitcoin_send_transaction: IDL.Func([send_transaction_request], [], []), + canister_info: IDL.Func( + [ + IDL.Record({ + canister_id: canister_id, + num_requested_changes: IDL.Opt(IDL.Nat64), + }), + ], + [ + IDL.Record({ + controllers: IDL.Vec(IDL.Principal), + module_hash: IDL.Opt(IDL.Vec(IDL.Nat8)), + recent_changes: IDL.Vec(change), + total_num_changes: IDL.Nat64, + }), + ], + [], + ), + canister_status: IDL.Func( + [IDL.Record({ canister_id: canister_id })], + [ + IDL.Record({ + status: IDL.Variant({ + stopped: IDL.Null, + stopping: IDL.Null, + running: IDL.Null, + }), + memory_size: IDL.Nat, + cycles: IDL.Nat, + settings: definite_canister_settings, + idle_cycles_burned_per_day: IDL.Nat, + module_hash: IDL.Opt(IDL.Vec(IDL.Nat8)), + reserved_cycles: IDL.Nat, + }), + ], + [], + ), + clear_chunk_store: IDL.Func( + [IDL.Record({ canister_id: canister_id })], + [], + [], + ), + create_canister: IDL.Func( + [ + IDL.Record({ + settings: IDL.Opt(canister_settings), + sender_canister_version: IDL.Opt(IDL.Nat64), + }), + ], + [IDL.Record({ canister_id: canister_id })], + [], + ), + delete_canister: IDL.Func( + [IDL.Record({ canister_id: canister_id })], + [], + [], + ), + deposit_cycles: IDL.Func( + [IDL.Record({ canister_id: canister_id })], + [], + [], + ), + ecdsa_public_key: IDL.Func( + [ + IDL.Record({ + key_id: IDL.Record({ name: IDL.Text, curve: ecdsa_curve }), + canister_id: IDL.Opt(canister_id), + derivation_path: IDL.Vec(IDL.Vec(IDL.Nat8)), + }), + ], + [ + IDL.Record({ + public_key: IDL.Vec(IDL.Nat8), + chain_code: IDL.Vec(IDL.Nat8), + }), + ], + [], + ), + http_request: IDL.Func( + [ + IDL.Record({ + url: IDL.Text, + method: IDL.Variant({ + get: IDL.Null, + head: IDL.Null, + post: IDL.Null, + }), + max_response_bytes: IDL.Opt(IDL.Nat64), + body: IDL.Opt(IDL.Vec(IDL.Nat8)), + transform: IDL.Opt( + IDL.Record({ + function: IDL.Func( + [ + IDL.Record({ + context: IDL.Vec(IDL.Nat8), + response: http_response, + }), + ], + [http_response], + ['query'], + ), + context: IDL.Vec(IDL.Nat8), + }), + ), + headers: IDL.Vec(http_header), + }), + ], + [http_response], + [], + ), + install_chunked_code: IDL.Func( + [ + IDL.Record({ + arg: IDL.Vec(IDL.Nat8), + wasm_module_hash: IDL.Vec(IDL.Nat8), + mode: IDL.Variant({ + reinstall: IDL.Null, + upgrade: IDL.Opt( + IDL.Record({ skip_pre_upgrade: IDL.Opt(IDL.Bool) }), + ), + install: IDL.Null, + }), + chunk_hashes_list: IDL.Vec(chunk_hash), + target_canister: canister_id, + sender_canister_version: IDL.Opt(IDL.Nat64), + storage_canister: IDL.Opt(canister_id), + }), + ], + [], + [], + ), + install_code: IDL.Func( + [ + IDL.Record({ + arg: IDL.Vec(IDL.Nat8), + wasm_module: wasm_module, + mode: IDL.Variant({ + reinstall: IDL.Null, + upgrade: IDL.Opt( + IDL.Record({ skip_pre_upgrade: IDL.Opt(IDL.Bool) }), + ), + install: IDL.Null, + }), + canister_id: canister_id, + sender_canister_version: IDL.Opt(IDL.Nat64), + }), + ], + [], + [], + ), + node_metrics_history: IDL.Func( + [ + IDL.Record({ + start_at_timestamp_nanos: IDL.Nat64, + subnet_id: IDL.Principal, + }), + ], + [ + IDL.Vec( + IDL.Record({ + timestamp_nanos: IDL.Nat64, + node_metrics: IDL.Vec(node_metrics), + }), + ), + ], + [], + ), + provisional_create_canister_with_cycles: IDL.Func( + [ + IDL.Record({ + settings: IDL.Opt(canister_settings), + specified_id: IDL.Opt(canister_id), + amount: IDL.Opt(IDL.Nat), + sender_canister_version: IDL.Opt(IDL.Nat64), + }), + ], + [IDL.Record({ canister_id: canister_id })], + [], + ), + provisional_top_up_canister: IDL.Func( + [IDL.Record({ canister_id: canister_id, amount: IDL.Nat })], + [], + [], + ), + raw_rand: IDL.Func([], [IDL.Vec(IDL.Nat8)], []), + sign_with_ecdsa: IDL.Func( + [ + IDL.Record({ + key_id: IDL.Record({ name: IDL.Text, curve: ecdsa_curve }), + derivation_path: IDL.Vec(IDL.Vec(IDL.Nat8)), + message_hash: IDL.Vec(IDL.Nat8), + }), + ], + [IDL.Record({ signature: IDL.Vec(IDL.Nat8) })], + [], + ), + start_canister: IDL.Func( + [IDL.Record({ canister_id: canister_id })], + [], + [], + ), + stop_canister: IDL.Func([IDL.Record({ canister_id: canister_id })], [], []), + stored_chunks: IDL.Func( + [IDL.Record({ canister_id: canister_id })], + [IDL.Vec(chunk_hash)], + [], + ), + uninstall_code: IDL.Func( + [ + IDL.Record({ + canister_id: canister_id, + sender_canister_version: IDL.Opt(IDL.Nat64), + }), + ], + [], + [], + ), + update_settings: IDL.Func( + [ + IDL.Record({ + canister_id: IDL.Principal, + settings: canister_settings, + sender_canister_version: IDL.Opt(IDL.Nat64), + }), + ], + [], + [], + ), + upload_chunk: IDL.Func( + [ + IDL.Record({ + chunk: IDL.Vec(IDL.Nat8), + canister_id: IDL.Principal, + }), + ], + [chunk_hash], + [], + ), + }); +}; +export const init = ({ IDL }) => { + return []; +}; diff --git a/packages/pic/src/management-canister.ts b/packages/pic/src/management-canister.ts deleted file mode 100644 index 321643b..0000000 --- a/packages/pic/src/management-canister.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { IDL } from '@dfinity/candid'; -import { Principal } from '@dfinity/principal'; - -export const MANAGEMENT_CANISTER_ID = Principal.fromText('aaaaa-aa'); - -export interface CanisterSettings { - controllers: Principal[]; - compute_allocation: [] | [bigint]; - memory_allocation: [] | [bigint]; - freezing_threshold: [] | [bigint]; -} - -export const CanisterSettings = IDL.Opt( - IDL.Record({ - controllers: IDL.Opt(IDL.Vec(IDL.Principal)), - compute_allocation: IDL.Opt(IDL.Nat), - memory_allocation: IDL.Opt(IDL.Nat), - freezing_threshold: IDL.Opt(IDL.Nat), - }), -); - -export interface CreateCanisterRequest { - settings: [] | [CanisterSettings]; - amount: [] | [bigint]; -} - -const CreateCanisterRequest = IDL.Record({ - settings: CanisterSettings, - amount: IDL.Opt(IDL.Nat), -}); - -export function encodeCreateCanisterRequest( - arg: CreateCanisterRequest, -): Uint8Array { - return new Uint8Array(IDL.encode([CreateCanisterRequest], [arg])); -} - -const CreateCanisterResponse = IDL.Record({ - canister_id: IDL.Principal, -}); - -export interface CreateCanisterResponse { - canister_id: Principal; -} - -export function decodeCreateCanisterResponse( - arg: Uint8Array, -): CreateCanisterResponse { - const [payload] = IDL.decode([CreateCanisterResponse], arg); - - // [TODO] - type check? - return payload as unknown as CreateCanisterResponse; -} - -const InstallCodeRequest = IDL.Record({ - arg: IDL.Vec(IDL.Nat8), - wasm_module: IDL.Vec(IDL.Nat8), - mode: IDL.Variant({ - reinstall: IDL.Null, - upgrade: IDL.Null, - install: IDL.Null, - }), - canister_id: IDL.Principal, -}); - -export interface InstallCodeRequest { - arg: Uint8Array; - wasm_module: Uint8Array; - mode: { reinstall?: null; upgrade?: null; install?: null }; - canister_id: Principal; -} - -export function encodeInstallCodeRequest(arg: InstallCodeRequest): Uint8Array { - return new Uint8Array(IDL.encode([InstallCodeRequest], [arg])); -} diff --git a/packages/pic/src/pocket-ic-types.ts b/packages/pic/src/pocket-ic-types.ts index d8f8141..e03b092 100644 --- a/packages/pic/src/pocket-ic-types.ts +++ b/packages/pic/src/pocket-ic-types.ts @@ -30,6 +30,7 @@ export interface CanisterFixture { * @param computeAllocation The compute allocation of the canister. * @param memoryAllocation The memory allocation of the canister. * @param freezingThreshold The freezing threshold of the canister. + * @param reservedCyclesLimit The reserved cycles limit of the canister. * * @category Types * @see [Principal](https://agent-js.icp.xyz/principal/classes/Principal.html) @@ -40,4 +41,5 @@ export interface CreateCanisterOptions { computeAllocation?: bigint; memoryAllocation?: bigint; freezingThreshold?: bigint; + reservedCyclesLimit?: bigint; } diff --git a/packages/pic/src/pocket-ic.ts b/packages/pic/src/pocket-ic.ts index 310a5c5..94a64b5 100644 --- a/packages/pic/src/pocket-ic.ts +++ b/packages/pic/src/pocket-ic.ts @@ -1,16 +1,16 @@ import { Principal } from '@dfinity/principal'; import { IDL } from '@dfinity/candid'; -import { optionalBigInt, readFileAsBytes } from './util'; +import { optionalArray, optionalBigInt, readFileAsBytes } from './util'; import { PocketIcServer } from './pocket-ic-server'; import { PocketIcClient } from './pocket-ic-client'; import { ActorInterface, Actor, createActorClass } from './pocket-ic-actor'; -import { - MANAGEMENT_CANISTER_ID, - decodeCreateCanisterResponse, - encodeCreateCanisterRequest, - encodeInstallCodeRequest, -} from './management-canister'; import { CanisterFixture, CreateCanisterOptions } from './pocket-ic-types'; +import { + _SERVICE as ManagementCanister, + idlFactory as ManagementCanisterIdl, +} from './candid/management-canister'; + +const MANAGEMENT_CANISTER_ID = Principal.fromText('aaaaa-aa'); /** * PocketIC is a local development environment for Internet Computer canisters. @@ -56,6 +56,7 @@ import { CanisterFixture, CreateCanisterOptions } from './pocket-ic-types'; export class PocketIc { private constructor( private readonly client: PocketIcClient, + private readonly managementCanisterActor: Actor, private readonly server?: PocketIcServer, ) {} @@ -74,8 +75,13 @@ export class PocketIc { public static async create(): Promise { const server = await PocketIcServer.start(); const client = await PocketIcClient.create(server.getUrl()); + const ManageCanisterActor = createActorClass( + ManagementCanisterIdl, + MANAGEMENT_CANISTER_ID, + client, + ); - return new PocketIc(client, server); + return new PocketIc(client, new ManageCanisterActor(), server); } /** @@ -94,7 +100,13 @@ export class PocketIc { */ public static async createFromUrl(url: string): Promise { const client = await PocketIcClient.create(url); - return new PocketIc(client); + const ManageCanisterActor = createActorClass( + ManagementCanisterIdl, + MANAGEMENT_CANISTER_ID, + client, + ); + + return new PocketIc(client, new ManageCanisterActor()); } /** @@ -169,26 +181,28 @@ export class PocketIc { ): Promise { const cycles = options.cycles ?? 1_000_000_000_000_000_000n; - const payload = encodeCreateCanisterRequest({ - settings: [ + this.managementCanisterActor.setPrincipal(sender); + const { canister_id } = + await this.managementCanisterActor.provisional_create_canister_with_cycles( { - controllers: options.controllers ?? [], - compute_allocation: optionalBigInt(options.computeAllocation), - memory_allocation: optionalBigInt(options.memoryAllocation), - freezing_threshold: optionalBigInt(options.freezingThreshold), + settings: [ + { + controllers: optionalArray(options.controllers), + compute_allocation: optionalBigInt(options.computeAllocation), + memory_allocation: optionalBigInt(options.memoryAllocation), + freezing_threshold: optionalBigInt(options.freezingThreshold), + reserved_cycles_limit: optionalBigInt( + options.reservedCyclesLimit, + ), + }, + ], + amount: [cycles], + sender_canister_version: [], + specified_id: [], }, - ], - amount: [cycles], - }); + ); - const res = await this.client.updateCall( - MANAGEMENT_CANISTER_ID, - sender, - 'provisional_create_canister_with_cycles', - payload, - ); - - return decodeCreateCanisterResponse(res).canister_id; + return canister_id; } /** @@ -229,21 +243,16 @@ export class PocketIc { wasm = await readFileAsBytes(wasm); } - const payload = encodeInstallCodeRequest({ + this.managementCanisterActor.setPrincipal(sender); + await this.managementCanisterActor.install_code({ arg: new Uint8Array(arg), canister_id: canisterId, mode: { install: null, }, wasm_module: new Uint8Array(wasm), + sender_canister_version: [], }); - - await this.client.updateCall( - MANAGEMENT_CANISTER_ID, - sender, - 'install_code', - payload, - ); } /** @@ -284,21 +293,16 @@ export class PocketIc { wasm = await readFileAsBytes(wasm); } - const payload = encodeInstallCodeRequest({ + this.managementCanisterActor.setPrincipal(sender); + await this.managementCanisterActor.install_code({ arg: new Uint8Array(arg), canister_id: canisterId, mode: { reinstall: null, }, wasm_module: new Uint8Array(wasm), + sender_canister_version: [], }); - - await this.client.updateCall( - MANAGEMENT_CANISTER_ID, - sender, - 'install_code', - payload, - ); } /** @@ -334,26 +338,26 @@ export class PocketIc { wasm: ArrayBufferLike | string, arg: ArrayBufferLike = new Uint8Array(), sender = Principal.anonymous(), + skipPreUpgrade = false, ): Promise { if (typeof wasm === 'string') { wasm = await readFileAsBytes(wasm); } - const payload = encodeInstallCodeRequest({ + this.managementCanisterActor.setPrincipal(sender); + await this.managementCanisterActor.install_code({ arg: new Uint8Array(arg), canister_id: canisterId, mode: { - upgrade: null, + upgrade: [ + { + skip_pre_upgrade: [skipPreUpgrade], + }, + ], }, wasm_module: new Uint8Array(wasm), + sender_canister_version: [], }); - - await this.client.updateCall( - MANAGEMENT_CANISTER_ID, - sender, - 'install_code', - payload, - ); } /** diff --git a/packages/pic/src/util/candid.ts b/packages/pic/src/util/candid.ts index 96f4d61..2ac2d35 100644 --- a/packages/pic/src/util/candid.ts +++ b/packages/pic/src/util/candid.ts @@ -3,3 +3,7 @@ export function optionalBigInt( ): [] | [bigint] { return value === undefined || value === null ? [] : [value]; } + +export function optionalArray(value: T[] | undefined | null): [] | [T[]] { + return value === undefined || value === null ? [] : [value]; +} diff --git a/packages/pic/tsconfig.json b/packages/pic/tsconfig.json index 68f92aa..ddb6bed 100644 --- a/packages/pic/tsconfig.json +++ b/packages/pic/tsconfig.json @@ -6,5 +6,6 @@ "declaration": true, "sourceMap": true, "stripInternal": true, + "allowJs": true, }, }