diff --git a/docs/generated/changelog.html b/docs/generated/changelog.html index fc7a839ac..1c4780c69 100644 --- a/docs/generated/changelog.html +++ b/docs/generated/changelog.html @@ -12,6 +12,7 @@

Agent-JS Changelog

Version x.x.x

diff --git a/e2e/node/basic/basic.test.ts b/e2e/node/basic/basic.test.ts index 1a1816404..4779f4eab 100644 --- a/e2e/node/basic/basic.test.ts +++ b/e2e/node/basic/basic.test.ts @@ -74,7 +74,12 @@ test('createCanister', async () => { // Make sure this doesn't fail. await getManagementCanister({ agent: await agent, - }).provisional_create_canister_with_cycles({ amount: [BigInt(1e12)], settings: [] }); + }).provisional_create_canister_with_cycles({ + amount: [BigInt(1e12)], + settings: [], + specified_id: [], + sender_canister_version: [], + }); }); test('withOptions', async () => { @@ -93,5 +98,10 @@ test('withOptions', async () => { // Make sure this doesn't fail. await getManagementCanister({ agent: await agent, - }).provisional_create_canister_with_cycles({ amount: [BigInt(1e12)], settings: [] }); + }).provisional_create_canister_with_cycles({ + amount: [BigInt(1e12)], + settings: [], + specified_id: [], + sender_canister_version: [], + }); }); diff --git a/packages/agent/src/actor.ts b/packages/agent/src/actor.ts index 6d1947314..a7fd26823 100644 --- a/packages/agent/src/actor.ts +++ b/packages/agent/src/actor.ts @@ -16,7 +16,7 @@ import { RequestId } from './request_id'; import { toHex } from './utils/buffer'; import { CreateCertificateOptions } from './certificate'; import managementCanisterIdl from './canisters/management_idl'; -import _SERVICE from './canisters/management_service'; +import _SERVICE, { canister_settings } from './canisters/management_service'; export class ActorCallError extends AgentError { constructor( @@ -173,11 +173,22 @@ export type ActorMethodMappedWithHttpDetails = { /** * The mode used when installing a canister. */ -export enum CanisterInstallMode { - Install = 'install', - Reinstall = 'reinstall', - Upgrade = 'upgrade', -} +export type CanisterInstallMode = + | { + reinstall: null; + } + | { + upgrade: + | [] + | [ + { + skip_pre_upgrade: [] | [boolean]; + }, + ]; + } + | { + install: null; + }; /** * Internal metadata for actors. It's an enhanced version of ActorConfig with @@ -196,6 +207,13 @@ export interface CreateActorClassOpts { httpDetails?: boolean; } +interface CreateCanisterSettings { + freezing_threshold?: bigint; + controllers?: Array; + memory_allocation?: bigint; + compute_allocation?: bigint; +} + /** * An actor base class. An actor is an object containing only functions that will * return a promise. These functions are derived from the IDL definition. @@ -230,7 +248,7 @@ export class Actor { }, config: ActorConfig, ): Promise { - const mode = fields.mode === undefined ? CanisterInstallMode.Install : fields.mode; + const mode = fields.mode === undefined ? { install: null } : fields.mode; // Need to transform the arg into a number array. const arg = fields.arg ? [...new Uint8Array(fields.arg)] : []; // Same for module. @@ -241,17 +259,37 @@ export class Actor { : config.canisterId; await getManagementCanister(config).install_code({ - mode: { [mode]: null } as any, + mode, arg, wasm_module: wasmModule, canister_id: canisterId, + sender_canister_version: [], }); } - public static async createCanister(config?: CallConfig): Promise { + public static async createCanister( + config?: CallConfig, + settings?: CreateCanisterSettings, + ): Promise { + function settingsToCanisterSettings(settings: CreateCanisterSettings): [canister_settings] { + return [ + { + controllers: settings.controllers ? [settings.controllers] : [], + compute_allocation: settings.compute_allocation ? [settings.compute_allocation] : [], + freezing_threshold: settings.freezing_threshold ? [settings.freezing_threshold] : [], + memory_allocation: settings.memory_allocation ? [settings.memory_allocation] : [], + }, + ]; + } + const { canister_id: canisterId } = await getManagementCanister( config || {}, - ).provisional_create_canister_with_cycles({ amount: [], settings: [] }); + ).provisional_create_canister_with_cycles({ + amount: [], + settings: settingsToCanisterSettings(settings || {}), + specified_id: [], + sender_canister_version: [], + }); return canisterId; } @@ -472,11 +510,14 @@ export type ManagementCanisterRecord = _SERVICE; /** * Create a management canister actor - * @param config + * @param config - a CallConfig */ export function getManagementCanister(config: CallConfig): ActorSubclass { - function transform(_methodName: string, args: unknown[], _callConfig: CallConfig) { - const first = args[0] as any; + function transform( + _methodName: string, + args: Record & { canister_id: string }[], + ) { + const first = args[0]; let effectiveCanisterId = Principal.fromHex(''); if (first && typeof first === 'object' && first.canister_id) { effectiveCanisterId = Principal.from(first.canister_id as unknown); diff --git a/packages/agent/src/canisters/management_idl.ts b/packages/agent/src/canisters/management_idl.ts index d9422f720..8a2875e38 100644 --- a/packages/agent/src/canisters/management_idl.ts +++ b/packages/agent/src/canisters/management_idl.ts @@ -1,25 +1,139 @@ /** * This file is generated from the candid for asset management. + * didc version: 0.3.6 */ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore export default ({ 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({ - controllers: IDL.Vec(IDL.Principal), freezing_threshold: IDL.Nat, + controllers: IDL.Vec(IDL.Principal), memory_allocation: IDL.Nat, compute_allocation: IDL.Nat, }); const canister_settings = IDL.Record({ - controllers: IDL.Opt(IDL.Vec(IDL.Principal)), freezing_threshold: IDL.Opt(IDL.Nat), + controllers: IDL.Opt(IDL.Vec(IDL.Principal)), 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 })], [ @@ -32,18 +146,92 @@ export default ({ IDL }) => { 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)), }), ], [], ), + clear_chunk_store: IDL.Func([IDL.Record({ canister_id: canister_id })], [], []), create_canister: IDL.Func( - [IDL.Record({ settings: IDL.Opt(canister_settings) })], + [ + 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({ @@ -51,20 +239,40 @@ export default ({ IDL }) => { wasm_module: wasm_module, mode: IDL.Variant({ reinstall: IDL.Null, - upgrade: 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 })], @@ -76,18 +284,50 @@ export default ({ IDL }) => { [], ), 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 })], [], []), - uninstall_code: 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], + [], + ), }); }; diff --git a/packages/agent/src/canisters/management_service.ts b/packages/agent/src/canisters/management_service.ts index 65ba49864..8efe3b63e 100644 --- a/packages/agent/src/canisters/management_service.ts +++ b/packages/agent/src/canisters/management_service.ts @@ -1,58 +1,266 @@ /** * This file is generated from the candid for asset management. + * didc version: 0.3.6 */ // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore import type { Principal } from '@dfinity/principal'; +import type { ActorMethod } from '@dfinity/agent'; +import type { IDL } from '@dfinity/candid'; + +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 { - controllers: [] | [Array]; freezing_threshold: [] | [bigint]; + controllers: [] | [Array]; 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 { - controllers: Array; freezing_threshold: bigint; + controllers: Array; memory_allocation: bigint; compute_allocation: bigint; } -export type user_id = Principal; -export type wasm_module = Array; +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 default interface _SERVICE { - canister_status: (arg_0: { canister_id: canister_id }) => Promise<{ - status: { stopped: null } | { stopping: null } | { running: null }; - memory_size: bigint; - cycles: bigint; - settings: definite_canister_settings; - module_hash: [] | [Array]; - }>; - create_canister: (arg_0: { - settings: [] | [canister_settings]; - }) => Promise<{ canister_id: canister_id }>; - delete_canister: (arg_0: { canister_id: canister_id }) => Promise; - deposit_cycles: (arg_0: { canister_id: canister_id }) => Promise; - install_code: (arg_0: { - arg: Array; - wasm_module: wasm_module; - mode: { reinstall: null } | { upgrade: null } | { install: null }; - canister_id: canister_id; - }) => Promise; - provisional_create_canister_with_cycles: (arg_0: { - settings: [] | [canister_settings]; - amount: [] | [bigint]; - }) => Promise<{ canister_id: canister_id }>; - provisional_top_up_canister: (arg_0: { - canister_id: canister_id; - amount: bigint; - }) => Promise; - raw_rand: () => Promise>; - start_canister: (arg_0: { canister_id: canister_id }) => Promise; - stop_canister: (arg_0: { canister_id: canister_id }) => Promise; - uninstall_code: (arg_0: { canister_id: canister_id }) => Promise; - update_settings: (arg_0: { - canister_id: Principal; - settings: canister_settings; - }) => Promise; + 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[]]; + } + >; + 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>; } +export declare const idlFactory: IDL.InterfaceFactory;