I’m trying to see if there’s interest on something like this, so I know how to plan the implementation. I’m currently hacking away at the code over at https://github.com/dfinity/agent-rs to get it to play nice with wasm32. The end goal would be to include it in a client-side framework like yew and being able to call canisters rust-rust without any middleman.
There are two areas where I think a rust-based full-stack would work great: game development and dapps that would benefit from SSR support (think using the same html! macro).
I’ve been playing with this over the week-end and I’ve managed to send queries and read data from the canister, and start the update flow. I’ll have to come up with an idiomatic way of handling the loop{} as to not block the main app thread (yew has Interval support, afaict). I’ve only done the anonymous parts yet, for signing stuff I’ll probably have to wrestle with secp256k1 support, as at a first glance that didn’t want to play nice with wasm32.
It will probably end up a bit more limited than the main agent-rs, but my goal is to have it work with basic web app usage (e.g. get data w/ queries and send data with updates). If there’s community interest I’ll probably put a bit more effort into making it pretty and take it as an exercise for building APIs that other people use
From a rust / game dev noob, this sounds quite interesting. The ability to coordinate a game client with an on-chain game server is attractive. One of the things that seemed to be a sticking point from some developers during the DSCVR game hackathon was validating game state on chain to prevent cheating.
Quick update on this: Queries and Updates work, read_state works from an Interval. I’ve also managed to make the BasicIdentity work, and the updates are being received correctly on the live canister.
record { id = 3_305_500_666 : nat32;
added = 1_642_788_872_285_566_078 : nat64;
done = false;
name = "This should be signed";
added_by = principal "535yc-uxytb-gfk7h-tny7p-vjkoe-i4krp-3qmcl-uqfgr-cpgej-yqtjq-rqe";};
record { id = 440_330_012 : nat32;
added = 1_642_789_030_246_049_454 : nat64;
done = false;
name = "This should be signed";
added_by = principal "wf3fv-4c4nr-7ks2b-xa4u7-kf3no-32glf-lf7e4-4ng4a-wwtlu-a2vnq-nae";}
These two principals are of type BasicIdentity::from_key_pair() where the private key is a vec![0;32] and vec![1;32] respectively.
I’m pretty stoked that I got everything going, and I’ve learned a bunch about the inner workings of IC messaging doing this. I had to change a couple of imports because they weren’t wasm compatible (openssl and ring are the main ones) and also dropped a lot of functionality on the way. The code is held by duct-tape and unwrap() at the moment, but the good thing is that it works
Next I plan to work on an abstraction for the canister similar to ic-utils.
My only unknown right now is how to support logging in with Internet Identity. As far as I can tell there is no code in the agent-rs code base that attempts to do that. Does anyone have any pointers as where to start? I would assume the flow is send user to identity.ic0.app, receive an event on success, parse the payload (what does II return? is it a kind of delegation? a private/public keypair? types?) and then create an identity from that. Any help would be appreciated here.
I’ve managed to complete the flow of opening the II window, sending the auth request, and receiving the delegations, all from rust! (well, with a lot of js_sys and gloo_* help, but still!)
INFO src/main.rs:108 Ok("{\"kind\":\"authorize-client-success\",
\"delegations\":[
{\"delegation\":
{\"pubkey\":
{\"0\":48,\"1\":42,\"2\":48,\"3\":5, [...]
Now onto learning how to create an identity from a delegation. I’m pretty close to having end-to-end functionality, straight from rust!