I have structured my code in a similar manner to how OpenChat have structured theirs. That is to say, I have the following structure
- my_canister
-- api
---- Cargo.toml
---- src
-- impl
---- Cargo.toml
---- src
API defines mostly just structs, types and enums that are used to define the interface of my canister methods. a typical file inside API folder looks like this
use candid::CandidType;
use serde::{ Deserialize, Serialize };
use types::TokenInfo;
#[derive(CandidType, Serialize, Deserialize, Debug)]
pub struct Args {
pub token_list: Vec<(String, TokenInfo)>,
}
#[derive(CandidType, Serialize, Deserialize, Debug, PartialEq, Eq)]
pub enum Response {
Success,
InternalError(String),
}
Then, inside the impl folder, i use the types from the API folder like so
#[update(guard = "caller_is_governance_principal")]
#[trace]
pub async fn set_reward_token_types(args: Args) -> Response {
// ... more code
}
At the end of my lib.rs
file inside the impl folder, I call export_candid!();
I then build and extract the candid information by doing something like this
cargo build --target wasm32-unknown-unknown --target-dir $BASE_CANISTER_PATH/my_canister/target --release --locked -p $1
candid-extractor "backend/canisters/my_canister/target/wasm32-unknown-unknown/release/my_canister_canister.wasm" > some_path_to_api_folder/can.did
The problem though, is that When i look at my extracted .did file i get very unexpected results.
type SnsMetadata = record {
url : opt text;
logo : opt text;
name : opt text;
description : opt text;
};
service : (record {}) -> {
set_reward_token_types : (record {}) -> (SnsMetadata);
}
What could be the problem here? I noticed that the i can remove #[update(hidden = true)]
or add the update=true it is respected in the extracted candid output but its like the types never seem to pull through.