is it really internal, though? This looks like a normal candid wrapper, exposing it as an external method:
I rather see a problem here, in that only the governance canister may call the method:
I would change that line in prod to also allow the controller to call the method. That is secure in prod, I think, and it would allow developers to call it if they deploy a CMC canister themselves. For this particular case I would just comment out the check and rebuild the CMC canister, if that is OK, @rabbithole . Great handle, by the way, especially when asking questions that take us down rabbit holes!
Alternatively you could deploy the CMC canister specifying yourself as the governance canister. Avoids recompiling. But seems somehow wrong. Let’s just whitelist controllers and be done with it.
I am sorry, I am out of time for now. Please try to get this to work and if it still doesn’t work, please ping back and I/we can have another look when we get the chance. I’m disappointed to have got only part of the way through the puzzle.
It would be great to get a custom cmc.wasm
to work in a local environment, after all, internet identity also has a build for developers.
I’m trying to build cmc.wasm
, I can come back with the result later, thank you very much!
One more question - how can I find out the subnet id that is deployed on my computer? The get_subnet_types_to_subnets
method returns an empty array.
The subnet ID is the same as the root key, for local dfx. In Rust I wrote the conversion as:
/// Gets the subnet ID
#[context("Failed to determine subnet ID.")]
async fn get_subnet_id(agent: &Agent) -> anyhow::Result<Principal> {
let root_key = agent
.status()
.await
.with_context(|| "Could not get agent status")?
.root_key
.with_context(|| "Agent should have fetched the root key.")?;
Ok(Principal::self_authenticating(root_key))
}
Since I am not very familiar with the Rust language, I wrote a node script to get subnet_id
:
import { Principal } from '@dfinity/principal';
import { getLocalHttpAgent } from './utils/agent.utils.mjs';
async function getSubnetId() {
const agent = await getLocalHttpAgent();
const status = await agent.status();
return Principal.selfAuthenticating(status.root_key).toText();
}
const subnetId = await getSubnetId();
console.log(subnetId);
I received a suspiciously long value:
jz726-l5fnc-4y635-dnhxc-fugxd-snmg6-q455t-h4zlv-2bqrn-qijin-hqe
I hope there is still no error…
I am not too familiar with the JS API but hopefully we can find the problem. Just by the name, though, I guess that the JS is taking the raw bytes. Principal::self_authenticating(X)
is sha224(x)
(28 bytes) followed by the byte “2” to yield 29 bytes in total: https://github.com/dfinity/candid/blob/a1eb218c4777d7a1be263f061d499dfc428136a2/rust/candid/src/types/principal.rs#L122
Nice! I found a similar method in @dfinity/principal
lib, now I get a short subnet_id
:
Principal.selfAuthenticating(status.root_key).toText()
I was able to apply the settings for CMC
! The canister is now created! Many thanks to everyone who tried to help and special thanks @bitdivine, later I will add all the code examples to the repository and edit this message.
Update: I pushed the changes to the project repository with a small readme for developers. I hope this will be useful to someone.