Skip to content

Commit

Permalink
Merge pull request #2105 from demergent-labs/auto_generate_idls
Browse files Browse the repository at this point in the history
automatically generate the management canister idl objects and types …
lastmjs authored Sep 19, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 5ebdff4 + 23e6b5c commit 884b142
Showing 22 changed files with 1,567 additions and 1,095 deletions.
102 changes: 0 additions & 102 deletions canisters/management/bitcoin.ts

This file was deleted.

191 changes: 0 additions & 191 deletions canisters/management/canister_info.ts

This file was deleted.

263 changes: 0 additions & 263 deletions canisters/management/canister_management.ts

This file was deleted.

124 changes: 0 additions & 124 deletions canisters/management/http_request.ts

This file was deleted.

143 changes: 103 additions & 40 deletions canisters/management/ic.did
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Taken from: https://github.com/dfinity/interface-spec/blob/6e00887946b612a1169964fc75ee14f57c0ce65d/spec/_attachments/ic.did
// Taken from: https://github.com/dfinity/interface-spec/blob/c28afe4269b14f102c78b69225b7c380b826cf0f/spec/_attachments/ic.did

// Copyright 2021 DFINITY Foundation
//
@@ -17,12 +17,19 @@
type canister_id = principal;
type wasm_module = blob;

type log_visibility = variant {
controllers;
public;
};

type canister_settings = record {
controllers : opt vec principal;
compute_allocation : opt nat;
memory_allocation : opt nat;
freezing_threshold : opt nat;
reserved_cycles_limit : opt nat;
log_visibility : opt log_visibility;
wasm_memory_limit : opt nat;
};

type definite_canister_settings = record {
@@ -31,6 +38,8 @@ type definite_canister_settings = record {
memory_allocation : nat;
freezing_threshold : nat;
reserved_cycles_limit : nat;
log_visibility : log_visibility;
wasm_memory_limit : nat;
};

type change_origin = variant {
@@ -83,17 +92,29 @@ type ecdsa_curve = variant {
secp256k1;
};

type schnorr_algorithm = variant {
bip340secp256k1;
ed25519;
};

type satoshi = nat64;

// TODO https://forum.dfinity.org/t/regtest-removed-from-management-canister-candid-file/35277
type bitcoin_network = variant {
mainnet;
testnet;
regtest;
regtest; // TODO Added by Demergent Labs
};

type bitcoin_address = text;

type block_hash = blob;
type bitcoin_block_hash = blob;

type bitcoin_block_header = blob;

type millisatoshi_per_byte = nat64;

type bitcoin_block_height = nat32;

type outpoint = record {
txid : blob;
@@ -115,30 +136,10 @@ type bitcoin_get_utxos_args = record {
};
};

type bitcoin_get_utxos_query_args = record {
address : bitcoin_address;
network : bitcoin_network;
filter : opt variant {
min_confirmations : nat32;
page : blob;
};
};

type bitcoin_get_current_fee_percentiles_args = record {
network : bitcoin_network;
};

type bitcoin_get_utxos_result = record {
utxos : vec utxo;
tip_block_hash : block_hash;
tip_height : nat32;
next_page : opt blob;
};

type bitcoin_get_utxos_query_result = record {
utxos : vec utxo;
tip_block_hash : block_hash;
tip_height : nat32;
tip_block_hash : bitcoin_block_hash;
tip_height : bitcoin_block_height;
next_page : opt blob;
};

@@ -148,22 +149,33 @@ type bitcoin_get_balance_args = record {
min_confirmations : opt nat32;
};

type bitcoin_get_balance_query_args = record {
address : bitcoin_address;
type bitcoin_get_balance_result = satoshi;

type bitcoin_get_current_fee_percentiles_args = record {
network : bitcoin_network;
min_confirmations : opt nat32;
};

type bitcoin_get_current_fee_percentiles_result = vec millisatoshi_per_byte;

type bitcoin_send_transaction_args = record {
transaction : blob;
network : bitcoin_network;
};

type millisatoshi_per_byte = nat64;
type bitcoin_get_block_headers_args = record {
start_height : bitcoin_block_height;
end_height : opt bitcoin_block_height;
network: bitcoin_network;
};

type bitcoin_get_block_headers_result = record {
tip_height : bitcoin_block_height;
block_headers : vec bitcoin_block_header;
};

type node_metrics = record {
node_id : principal;
num_blocks_total : nat64;
num_blocks_proposed_total : nat64;
num_block_failures_total : nat64;
};

@@ -200,6 +212,10 @@ type canister_install_mode = variant {
reinstall;
upgrade : opt record {
skip_pre_upgrade : opt bool;
wasm_memory_persistence : opt variant {
keep;
replace;
};
};
};

@@ -246,6 +262,12 @@ type canister_status_result = record {
cycles : nat;
reserved_cycles : nat;
idle_cycles_burned_per_day : nat;
query_stats: record {
num_calls_total: nat;
num_instructions_total: nat;
request_payload_bytes_total: nat;
response_payload_bytes_total: nat;
};
};

type canister_info_args = record {
@@ -274,12 +296,18 @@ type http_request_args = record {
method : variant { get; head; post };
headers : vec http_header;
body : opt blob;
transform : opt record {
function : func(record { response : http_request_result; context : blob }) -> (http_request_result) query;
context : blob;
};
transform : opt http_transform; // TODO added by Demergent Labs
};

// TODO added by Demergent Labs
type http_transform = record {
function : func(http_transform_args) -> (http_request_result) query;
context : blob;
};

// TODO this was added by Demergent Labs for use in the transform method parameters, it would be nice to upstream this
type http_transform_args = record { response : http_request_result; context : blob };

type ecdsa_public_key_args = record {
canister_id : opt canister_id;
derivation_path : vec blob;
@@ -301,6 +329,27 @@ type sign_with_ecdsa_result = record {
signature : blob;
};

type schnorr_public_key_args = record {
canister_id : opt canister_id;
derivation_path : vec blob;
key_id : record { algorithm : schnorr_algorithm; name : text };
};

type schnorr_public_key_result = record {
public_key : blob;
chain_code : blob;
};

type sign_with_schnorr_args = record {
message : blob;
derivation_path : vec blob;
key_id : record { algorithm : schnorr_algorithm; name : text };
};

type sign_with_schnorr_result = record {
signature : blob;
};

type node_metrics_history_args = record {
subnet_id : principal;
start_at_timestamp_nanos : nat64;
@@ -333,11 +382,19 @@ type stored_chunks_result = vec chunk_hash;

type upload_chunk_result = chunk_hash;

type bitcoin_get_balance_result = satoshi;
type fetch_canister_logs_args = record {
canister_id : canister_id;
};

type bitcoin_get_balance_query_result = satoshi;
type canister_log_record = record {
idx: nat64;
timestamp_nanos: nat64;
content: blob;
};

type bitcoin_get_current_fee_percentiles_result = vec millisatoshi_per_byte;
type fetch_canister_logs_result = record {
canister_log_records: vec canister_log_record;
};

service ic : {
create_canister : (create_canister_args) -> (create_canister_result);
@@ -361,18 +418,24 @@ service ic : {
ecdsa_public_key : (ecdsa_public_key_args) -> (ecdsa_public_key_result);
sign_with_ecdsa : (sign_with_ecdsa_args) -> (sign_with_ecdsa_result);

// Threshold Schnorr signature
schnorr_public_key : (schnorr_public_key_args) -> (schnorr_public_key_result);
sign_with_schnorr : (sign_with_schnorr_args) -> (sign_with_schnorr_result);

// bitcoin interface
bitcoin_get_balance : (bitcoin_get_balance_args) -> (bitcoin_get_balance_result);
bitcoin_get_balance_query : (bitcoin_get_balance_query_args) -> (bitcoin_get_balance_query_result) query;
bitcoin_get_utxos : (bitcoin_get_utxos_args) -> (bitcoin_get_utxos_result);
bitcoin_get_utxos_query : (bitcoin_get_utxos_query_args) -> (bitcoin_get_utxos_query_result) query;
bitcoin_send_transaction : (bitcoin_send_transaction_args) -> ();
bitcoin_get_current_fee_percentiles : (bitcoin_get_current_fee_percentiles_args) -> (bitcoin_get_current_fee_percentiles_result);
bitcoin_get_block_headers : (bitcoin_get_block_headers_args) -> (bitcoin_get_block_headers_result);

// metrics interface
node_metrics_history : (node_metrics_history_args) -> (node_metrics_history_result);

// provisional interfaces for the pre-ledger world
provisional_create_canister_with_cycles : (provisional_create_canister_with_cycles_args) -> (provisional_create_canister_with_cycles_result);
provisional_top_up_canister : (provisional_top_up_canister_args) -> ();
};

// canister logging
fetch_canister_logs : (fetch_canister_logs_args) -> (fetch_canister_logs_result) query;
};
1,144 changes: 1,105 additions & 39 deletions canisters/management/index.ts

Large diffs are not rendered by default.

56 changes: 0 additions & 56 deletions canisters/management/t_ecdsa.ts

This file was deleted.

4 changes: 2 additions & 2 deletions src/lib/experimental/fetch/http.ts
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import '../experimental';

import { inflate } from 'pako';

import { HttpTransform } from '../../../../canisters/management';
import { http_transform } from '../../../../canisters/management';
import { ic } from '../ic';
import { azleFetch, serialize } from '.';
import { AzleFetchResponse } from './response';
@@ -133,7 +133,7 @@ function getHttpMethod(init?: RequestInit | undefined) {
};
}

function getHttpTransform(): [] | [HttpTransform] {
function getHttpTransform(): [] | [http_transform] {
if (globalThis._azleOutgoingHttpOptionsTransformMethodName === undefined) {
return [];
}
12 changes: 6 additions & 6 deletions src/lib/stable/ic_apis/call.ts
Original file line number Diff line number Diff line change
@@ -2,17 +2,17 @@ import { IDL } from '@dfinity/candid';
import { Principal } from '@dfinity/principal';
import { v4 } from 'uuid'; // TODO is uuid experimental?

export async function call(
export async function call<Args extends any[] | undefined, Return = any>(
canisterId: Principal | string,
method: string,
options?: {
paramIdlTypes?: IDL.Type[];
returnIdlType?: IDL.Type;
args?: any[];
payment?: bigint;
args?: Args;
payment?: bigint; // TODO this should be called cycles: https://github.com/demergent-labs/azle/issues/2104
raw?: Uint8Array;
}
): Promise<any> {
): Promise<Return> {
// TODO this should use a Result remember
return new Promise((resolve, reject) => {
if (globalThis._azleIc === undefined) {
@@ -33,11 +33,11 @@ export async function call(
result: ArrayBuffer
): void => {
if (raw !== undefined) {
resolve(new Uint8Array(result));
resolve(new Uint8Array(result) as Return);
} else {
const idlType =
returnTypeIdl === undefined ? [] : [returnTypeIdl];
resolve(IDL.decode(idlType, result)[0]);
resolve(IDL.decode(idlType, result)[0] as Return);
}

delete globalThis._azleResolveIds[globalResolveId];
96 changes: 55 additions & 41 deletions tests/end_to_end/candid_rpc/class_syntax/bitcoin/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,27 @@
import { call, IDL, update } from 'azle';
import {
GetBalanceArgs,
GetCurrentFeePercentilesArgs,
GetUtxosArgs,
GetUtxosResult,
MillisatoshiPerByte,
Satoshi,
SendTransactionArgs
bitcoin_get_balance_args,
bitcoin_get_balance_result,
bitcoin_get_current_fee_percentiles_args,
bitcoin_get_current_fee_percentiles_result,
bitcoin_get_utxos_args,
bitcoin_get_utxos_result,
bitcoin_send_transaction_args
} from 'azle/canisters/management';

const BITCOIN_API_CYCLE_COST = 100_000_000n;
const BITCOIN_BASE_TRANSACTION_COST = 5_000_000_000n;
const BITCOIN_CYCLE_COST_PER_TRANSACTION_BYTE = 20_000_000n;

export default class {
@update([IDL.Text], Satoshi)
async getBalance(address: string): Promise<Satoshi> {
return await call('aaaaa-aa', 'bitcoin_get_balance', {
paramIdlTypes: [GetBalanceArgs],
returnIdlType: Satoshi,
@update([IDL.Text], bitcoin_get_balance_result)
async getBalance(address: string): Promise<bitcoin_get_balance_result> {
return await call<
[bitcoin_get_balance_args],
bitcoin_get_balance_result
>('aaaaa-aa', 'bitcoin_get_balance', {
paramIdlTypes: [bitcoin_get_balance_args],
returnIdlType: bitcoin_get_balance_result,
args: [
{
address,
@@ -30,11 +33,14 @@ export default class {
});
}

@update([], IDL.Vec(MillisatoshiPerByte))
async getCurrentFeePercentiles(): Promise<MillisatoshiPerByte[]> {
return await call('aaaaa-aa', 'bitcoin_get_current_fee_percentiles', {
paramIdlTypes: [GetCurrentFeePercentilesArgs],
returnIdlType: IDL.Vec(MillisatoshiPerByte),
@update([], bitcoin_get_current_fee_percentiles_result)
async getCurrentFeePercentiles(): Promise<bitcoin_get_current_fee_percentiles_result> {
return await call<
[bitcoin_get_current_fee_percentiles_args],
bitcoin_get_current_fee_percentiles_result
>('aaaaa-aa', 'bitcoin_get_current_fee_percentiles', {
paramIdlTypes: [bitcoin_get_current_fee_percentiles_args],
returnIdlType: bitcoin_get_current_fee_percentiles_result,
args: [
{
network: { regtest: null }
@@ -44,20 +50,24 @@ export default class {
});
}

@update([IDL.Text], GetUtxosResult)
async getUtxos(address: string): Promise<GetUtxosResult> {
return await call('aaaaa-aa', 'bitcoin_get_utxos', {
paramIdlTypes: [GetUtxosArgs],
returnIdlType: GetUtxosResult,
args: [
{
address,
filter: [],
network: { regtest: null }
}
],
payment: BITCOIN_API_CYCLE_COST
});
@update([IDL.Text], bitcoin_get_utxos_result)
async getUtxos(address: string): Promise<bitcoin_get_utxos_result> {
return await call<[bitcoin_get_utxos_args], bitcoin_get_utxos_result>(
'aaaaa-aa',
'bitcoin_get_utxos',
{
paramIdlTypes: [bitcoin_get_utxos_args],
returnIdlType: bitcoin_get_utxos_result,
args: [
{
address,
filter: [],
network: { regtest: null }
}
],
payment: BITCOIN_API_CYCLE_COST
}
);
}

@update([IDL.Vec(IDL.Nat8)], IDL.Bool)
@@ -67,16 +77,20 @@ export default class {
BigInt(transaction.length) *
BITCOIN_CYCLE_COST_PER_TRANSACTION_BYTE;

await call('aaaaa-aa', 'bitcoin_send_transaction', {
paramIdlTypes: [SendTransactionArgs],
args: [
{
transaction,
network: { regtest: null }
}
],
payment: transactionFee
});
await call<[bitcoin_send_transaction_args], void>(
'aaaaa-aa',
'bitcoin_send_transaction',
{
paramIdlTypes: [bitcoin_send_transaction_args],
args: [
{
transaction,
network: { regtest: null }
}
],
payment: transactionFee
}
);

return true;
}
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ export default class {
candidArgs: string,
payment: bigint
): Promise<string> {
const result = await call(canisterId, method, {
const result = await call<undefined>(canisterId, method, {
raw: candidEncode(candidArgs),
payment
});
Original file line number Diff line number Diff line change
@@ -9,11 +9,9 @@ import {
update
} from 'azle';
import {
FUNCS as managementCanister,
HttpRequestArgs,
HttpResponse,
HttpTransformArgs,
PRINCIPAL
http_request_args,
http_request_result,
http_transform_args
} from 'azle/canisters/management';

export default class {
@@ -48,8 +46,8 @@ export default class {
return await getBlockByNumber(url, number);
}

@query([HttpTransformArgs], HttpResponse)
ethTransform(args: HttpTransformArgs): HttpResponse {
@query([http_transform_args], http_request_result)
ethTransform(args: http_transform_args): http_request_result {
return {
...args.response,
headers: []
@@ -61,12 +59,12 @@ async function getBalance(
url: string,
ethereumAddress: string
): Promise<string> {
const httpResponse = await call(
PRINCIPAL,
managementCanister.http_request,
const httpResponse = await call<[http_request_args], http_request_result>(
Principal.fromText('aaaaa-aa'),
'http_request',
{
paramIdlTypes: [HttpRequestArgs],
returnIdlType: HttpResponse,
paramIdlTypes: [http_request_args],
returnIdlType: http_request_result,
args: [
{
url,
@@ -100,15 +98,15 @@ async function getBalance(
}
);

return new TextDecoder().decode(httpResponse.body.buffer);
return new TextDecoder().decode(Uint8Array.from(httpResponse.body));
}
async function getBlockByNumber(url: string, number: number): Promise<string> {
const httpResponse = await call(
PRINCIPAL,
managementCanister.http_request,
const httpResponse = await call<http_request_args[], http_request_result>(
Principal.fromText('aaaaa-aa'),
'http_request',
{
paramIdlTypes: [HttpRequestArgs],
returnIdlType: HttpResponse,
paramIdlTypes: [http_request_args],
returnIdlType: http_request_result,
args: [
{
url,
@@ -142,5 +140,5 @@ async function getBlockByNumber(url: string, number: number): Promise<string> {
}
);

return new TextDecoder().decode(httpResponse.body.buffer);
return new TextDecoder().decode(Uint8Array.from(httpResponse.body));
}
369 changes: 209 additions & 160 deletions tests/end_to_end/candid_rpc/class_syntax/management_canister/src/index.ts

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { call, caller, IDL, trap, update } from 'azle';
import {
EcdsaPublicKeyArgs,
EcdsaPublicKeyResult,
SignWithEcdsaArgs,
SignWithEcdsaResult
ecdsa_public_key_args,
ecdsa_public_key_result,
sign_with_ecdsa_args,
sign_with_ecdsa_result
} from 'azle/canisters/management';

const PublicKey = IDL.Record({
@@ -24,8 +24,9 @@ export default class {
@update([], PublicKey)
async publicKey(): Promise<PublicKey> {
const publicKeyResult = await getPublicKeyResult();

return {
publicKey: publicKeyResult.public_key
publicKey: Uint8Array.from(publicKeyResult.public_key)
};
}

@@ -38,44 +39,52 @@ export default class {
const signatureResult = await getSignatureResult(messageHash);

return {
signature: signatureResult.signature
signature: Uint8Array.from(signatureResult.signature)
};
}
}

async function getPublicKeyResult(): Promise<EcdsaPublicKeyResult> {
return await call('aaaaa-aa', 'ecdsa_public_key', {
paramIdlTypes: [EcdsaPublicKeyArgs],
returnIdlType: EcdsaPublicKeyResult,
args: [
{
canister_id: [],
derivation_path: [caller().toUint8Array()],
key_id: {
curve: { secp256k1: null },
name: 'dfx_test_key'
async function getPublicKeyResult(): Promise<ecdsa_public_key_result> {
return await call<[ecdsa_public_key_args], ecdsa_public_key_result>(
'aaaaa-aa',
'ecdsa_public_key',
{
paramIdlTypes: [ecdsa_public_key_args],
returnIdlType: ecdsa_public_key_result,
args: [
{
canister_id: [],
derivation_path: [caller().toUint8Array()],
key_id: {
curve: { secp256k1: null },
name: 'dfx_test_key'
}
}
}
]
});
]
}
);
}

async function getSignatureResult(
messageHash: Uint8Array
): Promise<SignWithEcdsaResult> {
return await call('aaaaa-aa', 'sign_with_ecdsa', {
paramIdlTypes: [SignWithEcdsaArgs],
returnIdlType: SignWithEcdsaResult,
args: [
{
message_hash: messageHash,
derivation_path: [caller().toUint8Array()],
key_id: {
curve: { secp256k1: null },
name: 'dfx_test_key'
): Promise<sign_with_ecdsa_result> {
return await call<[sign_with_ecdsa_args], sign_with_ecdsa_result>(
'aaaaa-aa',
'sign_with_ecdsa',
{
paramIdlTypes: [sign_with_ecdsa_args],
returnIdlType: sign_with_ecdsa_result,
args: [
{
message_hash: messageHash,
derivation_path: [caller().toUint8Array()],
key_id: {
curve: { secp256k1: null },
name: 'dfx_test_key'
}
}
}
],
payment: 10_000_000_000n
});
],
payment: 10_000_000_000n
}
);
}
Original file line number Diff line number Diff line change
@@ -9,17 +9,20 @@ import {
update
} from 'azle';
import {
HttpRequestArgs,
HttpResponse,
HttpTransformArgs
http_request_args,
http_request_result,
http_transform_args
} from 'azle/canisters/management';

export default class {
@update([], IDL.Text)
async xkcd(): Promise<string> {
const httpResponse = await call('aaaaa-aa', 'http_request', {
paramIdlTypes: [HttpRequestArgs],
returnIdlType: HttpResponse,
const httpResponse = await call<
[http_request_args],
http_request_result
>('aaaaa-aa', 'http_request', {
paramIdlTypes: [http_request_args],
returnIdlType: http_request_result,
args: [
{
url: `https://xkcd.com/642/info.0.json`,
@@ -43,12 +46,12 @@ export default class {
payment: 50_000_000n
});

return new TextDecoder().decode(httpResponse.body);
return new TextDecoder().decode(Uint8Array.from(httpResponse.body));
}

@update([], HttpResponse, { manual: true })
@update([], http_request_result, { manual: true })
async xkcdRaw(): Promise<void> {
const httpResponse = await call(
const httpResponse = await call<undefined, Uint8Array>(
Principal.fromText('aaaaa-aa'),
'http_request',
{
@@ -71,8 +74,8 @@ export default class {
reply({ raw: httpResponse });
}

@query([HttpTransformArgs], HttpResponse)
xkcdTransform(args: HttpTransformArgs): HttpResponse {
@query([http_transform_args], http_request_result)
xkcdTransform(args: http_transform_args): http_request_result {
return {
...args.response,
headers: []
Original file line number Diff line number Diff line change
@@ -53,9 +53,11 @@ export default Canister({
settings: {
controllers: [],
compute_allocation: [1n],
log_visibility: [],
memory_allocation: [3_000_000n],
freezing_threshold: [2_000_000n],
reserved_cycles_limit: []
reserved_cycles_limit: [],
wasm_memory_limit: []
},
sender_canister_version: []
}

0 comments on commit 884b142

Please sign in to comment.