Enhancement: stronger typing of `wallet_send`
crusso opened this issue · 4 comments
This is the current Candid for wallet_send
wallet_send: (record { canister: principal; amount: nat64 }) -> ();
At the moment, it's just taking a principal, p
, with no way of saying what interface that principal is expected to support.
wallet_rs.wallet_send
then blindly calls method p.wallet_receive()
assuming it returns some result.
I think the wallet API could (perhaps) use a more strongly typed wallet_send
method, something like the higher-order :
wallet_send: (record { callback: () -> record { accepted : nat64 }; amount: nat64 }) -> ()
(excuse my Candid)
to make the contract clearer and safer. If we want to insist on the wallet_receive
name, then the argument could be whole service with a single method instead.
wallet_send: (record { canister: service { wallet_receive: () -> record { accepted : nat64 } }; amount: nat64 }) -> ()
Discovered debugging dfinity/examples#71 (@lsgunnlsgunn hello_cycles
example).
@crusso How do you specify the callback in dfx or frontend or rust? What is a function reference in Candid encoding?
Candid textual format can express function values via the syntax func "w7x7r-cok77-xa"."method_name"
@lsgunnlsgunn is already tripping over the weak typing. She implemented an actor with a wallet_receive
method with the wrong return type, but the rust wallet ignores the result so it actually didn't matter (for now).
On the other hand, since the candid values for actor and functions are untyped, I guess we only gain a more descriptive wallet interface but no actual additional safety when used from dfx rather than, say, a well-typed Motoko program.
Resolved in #130 - arbitrary canister functions are no longer called by the wallet_send function, which instead calls the management canister's deposit_cycles function.