Hey, I would like to call the IC from a flutter app.
So far, I managed to run rust code and import the ic_agent module. I tried to make a query call but didn’t receive any answer. This is how I tried to make the call:
pub async fn query_call(canister_id: &str, method_name: &str) -> String {
// create random identity for agent
let rng = ring::rand::SystemRandom::new();
let key_pair = ring::signature::Ed25519KeyPair::generate_pkcs8(&rng)
.expect("Could not generate a key pair.");
let identity = BasicIdentity::from_key_pair(
ring::signature::Ed25519KeyPair::from_pkcs8(key_pair.as_ref())
.expect("Could not read the key pair."),
);
// initialize agent and canister_id
let url = format!("/api/v2/canister/{}/query", canister_id);
let agent = ic_agent::Agent::builder()
.with_identity(identity)
.with_url(url)
.build()
.unwrap();
let canister_id_principal = Principal::from_text(canister_id).unwrap();
// use QueryBuilder to make query call
let query_builder = QueryBuilder::new(&agent, canister_id_principal, String::from(method_name));
let response = query_builder.call().await;
match response {
Ok(reply) => return String::from_utf8_lossy(&reply).to_string(),
Err(AgentError::ReplicaError {
reject_code,
reject_message,
}) => return format!("Error {} occured with message: {}", reject_code, reject_message),
Err(_) => return "Error occured other than ReplicaError!".to_string(),
}
}
What did I do wrong? Is QueryBuilder the right object for this?
Alright, switching to tokio 1.2.0 instead of 0.2.0 did the trick
With the ic0.app ending I can reach the replica, but it returns a 404 error.
Any idea why this happens?
The canister and function work when called by the dfx command line tool.
Yeah that’s true
I tried to deploy a canister on the Beta Mainnet now, but it’s not possible just yet as is described here:
Therefore, I’m deploying locally for now. Calling the query with
let response = query_builder.with_arg("everyone".to_string()).call().await;
returned this error: IDL error: missing magic bytes.
Changing the string to .with_arg("DIDLeveryone".to_string()) as you suggested here:
got me to the next error: IDL error: too many types.
I’m not sure what it means though.
Is there maybe some other convention from candid that needs to be considered?
Although calling the exact same code from within a flutter app gives me an empty string… (This is with calling the localhost as 10.0.2.2 from an android emulator)
Anyway, I’m going to try this again when the public app subnets are unlocked.
Do you know how I can candid en-code a record in the rust? Which rust-object-type should I pass in the candid::Encode!() for the candid-code of a candid-record?