examples
examples copied to clipboard
Illustrate adding a wallet_receive function to the default template project
WIP to try out adding a wallet_receive function to a Motoko program to work with the Rust wallet created by default for local development. I'm trying to test how someone might add the wallet-related functions using our quick start demo project.
Demo
- Clone the project.
- Change to the
hello_cycles
directory. - Run
dfx start --clean --background
. - Run
dfx deploy --argument '(20000000000000)'
. The argument is required because this is an actor class. Note the canister identifier for thehello_cycles
canister. - Run
dfx canister call hello_cycles greet '("everyone")'
to verify the default function works as expected. - Run
more .dfx/local/wallets.json
to find the wallet canister identifier. - Run a command similar to the following to try to send cycles to the
hello_cycles
canister from the local wallet.dfx canister call rwlgt-iiaaa-aaaaa-aaaaa-cai wallet_send '(record { canister = principal "rrkah-fqaaa-aaaaa-aaaaq-cai"; amount = (2000000000000:nat64); } )'
rwlgt-iiaaa-aaaaa-aaaaa-cai
is the wallet canister for the active identity created automatically.
rrkah-fqaaa-aaaaa-aaaaq-cai
is the hello_cycles canister with the test wallet_receive
function.
Currently, this returns an error like this:
The Replica returned an error: code 5, message: "Canister rwlgt-iiaaa-aaaaa-aaaaa-cai trapped explicitly: Custom("No more values to deserialize")"
Possibly because the wallet canister expects an event?
I took a quick look, but didn't try to test my proposal.
My hunch is that the rust wallet is failing to deserialize the result of its internal call to Motoko wallet_receive
.
If that is meant to have the same signature as the wallet's own wallet_receive
method, then the Motoko wallet_receive
should be returning a Motoko { accepted : Nat64 }
(Candid record { accepted : nat64; }
, I guess).
In your code, Motoko wallet_receive
has type () -> async ()
, so is returning no values (I think).
Careful, Motoko's accept
function returns a Nat
, not Nat64
, so you'll need to do a conversion via 'Nat64.fromNat(n)' before returning the record.
If this doesn't work for you, let me know and I'll try myself tomorrow (or just tell me you didn't get around to it).
#72 contains the fix as a diff to your branch.
Seems to work, without errror, but I can't call hello_cycles.wallet_balance()
from dfx
because the assert fails for some reason.
crusso@crusso-Virtual-Machine:~/examples/motoko/hello_cycles$ dfx canister call rwlgt-iiaaa-aaaaa-aaaaa-cai wallet_send '(record { canister = principal "rrkah-fqaaa-aaaaa-aaaaq-cai"; amount = (2000000000000:nat64); } )'
()
crusso@crusso-Virtual-Machine:~/examples/motoko/hello_cycles$ dfx canister call hello_cycles wallet_balance '()'
The Replica returned an error: code 5, message: "Canister rrkah-fqaaa-aaaaa-aaaaq-cai trapped explicitly: assertion failed at /home/crusso/examples/motoko/hello_cycles/src/hello_cycles/main.mo:13.5-13.33"
Who is the owner when dfx does a call or install now - is it the wallet, user or something else?
That's a good question. I can see my current identity and get the principal for that, but there isn't currently a get-controller
(AFAIK) command to see the current controller for a canister. I'll file an issue for that.
https://github.com/dfinity/sdk/issues/1470
I removed the assert
and my little example works:
dfx deploy --argument '(120000000000000)'
... Deployed canisters.
dfx canister call hello_cycles greet '("everyone")'
("Hello, everyone!")
dfx canister call hello_cycles wallet_balance
(0)
dfx canister call rwlgt-iiaaa-aaaaa-aaaaa-cai wallet_send '(record { canister = principal "rrkah-fqaaa-aaaaa-aaaaq-cai"; amount = (2000000000000:nat64); } )'
()
dfx canister call hello_cycles wallet_balance
(2_000_000_000_000)
Glad to it see it works. I wonder, when you install the canister, does the wallet become the caller of the install method? That might explain why the assert failed. Maybe add a method to display the textual version of owner and msg.caller, so you can see which it is? Better yet, ask Hans...
Might be nice to implement wallet_send
too, so you can illustrate Cycles.add()
and Cycles.refunded()
.
Yep, it would be cool to either extend this example or add a second version with the wallet_send
, Cycles.add()
, and Cycles.refunded()
operations.
I thought this was a good starting point because people will get the Rust wallet automatically but then might need to add the receive function to their existing canisters that aren't wallets.
I really appreciate your help in getting these little examples working!