Question about deposit_cycles

I’m implementing deposit_cycles in Azle, and I am not quite sure how the cycles get sent in Rust. Can someone confirm my thinking here?

I imagine that I need to call the management canister’s deposit_cycles method using the call_with_payment or call_with_payment128 functions, is that correct?

Correct. call_with_payment128 specifies the cycles that will be transferred.

A canister can also implement a function to accept cycles from anyone calling it, like so:

#[update]
fn wallet_receive() -> () {
    let amount = ic_cdk::api::call::msg_cycles_available128();
    if amount > 0 {
        ic_cdk::api::call::msg_cycles_accept128(amount);
    }
}

Using call_with_payment_128() on this fn works fine and the canister is credited.

ic_cdk::api::call::call_with_payment128(
        index_canister_id,
        "wallet_receive",
        {},
        cycles_amount,
    )
    .await

I imagine that I need to call the management canister’s deposit_cycles method using the call_with_payment or call_with_payment128 functions, is that correct?

As far as I understand only the controllers of a canister can call the management canister’s deposit_cycles. The code above is one of the ways to work around that. If you add that fn, anyone can add cycles to your canister.

Thanks to both of you!

This is incorrect, anyone can call deposit_cycles. wallet_receive does not exist to work around a limitation of deposit_cycles, but rather because when it was created, deposit_cycles did not exist.

Happy to stand corrected! I remember reading that the “cycles tipjar” project needed you to add a special canister as a controller so that their service works. I wonder if they know that the limitation was lifted sometime after they coded their app.

A permission-based limitation on giving a canister cycles never existed; previously the canister needed an explicit function for it to be possible, and now it does not. The tip jar requires the black hole as a controller because it reads a canister’s cycle balance in order to distribute based on need, which does require being a controller.

Thanks for the thorough explanation! I must have jumped to the conclusion that you can’t send cycles on my own :blush: