Brainstorming ideas to make the Rust and Web Client super easy and intuitive to use #854
Replies: 6 comments 6 replies
|
One quick comment I have is with regards to |
|
I agree there is room for making the client much more accessible in various ways. I also think focusing on user feedback will provide the most value here, so thanks for opening the discussion and providing some ideas! I'll try to add some comments about specific points and then provide some other ideas (probably in a different comment).
At this point (as of #782), actually the simplest way to build the client in an let mut client = ClientBuilder::new()
.build()
.await?;
I think we also have a specific
I think I'd prefer it as it is right now (passing the directory), but not a strong opinion at all so I wouldn't mind changing the default.
I agree with the sentiment here, there's room to polish the structures and usability. The defaults you are proposing are based on the
We use trait objects for the main client components rather than generics, which is more a consequence of the client not being too opinionated as you imply and as mentioned above. Maybe there is room to make something on top of the client that provides better defaults and be a better option for higher-level uses? Or maybe we could make it more opinionated too. There is also the work for making more components that can be taken and used in a stand-alone manner (though while related, it's also independent of this argument).
This also feels very related to the above points.
I think this is more a consequence of the lifecycle of a transaction in the node/protocol. Unless basic validations fail, the transaction is accepted at the RPC level (so as far as the client goes, the submission went well) and sent to the mempool so that the block producer can eventually attempt to include it in a block. Up until that point, some things could happen that could revert the transaction (expired transaction or batch, another transaction using the same input notes just before, etc.). I believe the RPC endpoint should return an error if something is wrong when submitting the proof (if not, we should take a look). Though this only involves verifying the proof itself, as far as I remember. With more recent and not so recent changes, we are adding support for discarded transactions with a way of identifying why transactions were reverted, but these updates can only be received as part of the
At the core of mostof these arguments is how we should balance some attributes of the client while trying to make it much easier and intuitive to use. In many environments, there is this pattern of providing functionality which splits SDKs or APIs into two different packages or interfaces: a more "native" one and a higher level one which is more opinionated, maybe less configurable and less powerful that wraps around the native package and makes it easier to access a system for entry-level users. The CLI sort of works as the more opinionated wrapper right now, but from a library perspective maybe we could do something more toward that model. It wouldn't have to be a different crate necessarily but maybe a better defined set of functionality which could be used as the default most of the time. |
One potential conceptual simplification we can make is to have |
|
Right now the CLI works both as a tool that simplifies the interaction with the Miden network and also as an example use case for the client. I think it works well for the former but it is not as useful for the latter as it is more of a wrapper for the client's functionality. We could have more standalone examples of use cases for the client. Small, well documented programs that explore the client's functionality. Similar to the integration tests but better documented, and maybe with some real world use cases and not just for testing purposes. One of the cons with this is that the client's interface is not stable right now so these would maybe need to change a lot in each PR (similar to what happens with the integration tests). We could make it so that these examples are only updated for each stable version. |
|
Posting here some takeaways from the recent discussion mixed with my two cents:
|
|
If we decide to use OPFS, we can re-use the logic of the Rust client with SqliteStore #1008. Also probably a radical idea but may worth it - making the rust client sync instead of async (in a similar vein to https://github.com/algesten/ureq):
So in the base Rust client we make minimal assumptions about future runtime - the language runtime can then make it async via threads, pooling etc (e.g. web would run the code in a dedicated worker with message passing with the main thread) @igamigo @tomyrd guys, what do you think also about storing keys in the sqlite for uniformity? |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I am starting this discussion to brainstorm ideas on how to make the Miden client as easy to use as possible.
The Miden client is one of the most critical pieces of the Miden protocol. This is because it is most likely the first Miden repository any new application / smart contract developer coming to Miden will interact with. This means making it as simple and intuitive to use is critical to make developers have a good first experience building applications on Miden.
Many experienced smart contract developers who are experts in Solidity or TypeScript may be less comfortable building with Rust. While we should support experienced Rust developers, we shouldn't exclude smart contract developers from other ecosystems who aren't as familiar with Rust-based smart contract development. This means that the Client should have opinionated sane defaults, but keep the ability for flexibility.
Last week we had an internal hackathon to build a basic application on Miden which led to finding a lot of potential areas of improvement. This is by no means a criticism of the client, this is just to start a brainstorm discussion on how to make the Client super easy to use.
Concretely, these are some things I think would make the Miden Rust client even easier to use. These are in no specific order:
1) Make Client initialization even easier
PR #741 made initialization easier, however, there are still improvements to be made.
Currently this is the easiest way to initialize the client:
This is unintuitive, because developers want to initialize the client via
Client::new(). I also think that we should have sane defaults for.with_rpc()and.with_filesystem_keystore().The
.with_rpc()method should be able to just take a string like this:with_rpc("https://rpc.testnet.miden.io")Also, the
.with_filesystem_keystore()method should default to using "./keystore" as the default path, which just creates a/keystoredirectory at the root of the project.I think the end goal of client initialization should look something like this:
or:
or:
Using
Client::new()is much more intuitive as opposed toClientBuilder::new().some_chain_of_methods().2) Use less Rust generics!
I think this might be a bit of a contentious issue / hot take, but I think the Miden Rust client should be more opinionated. This is because Miden is already difficult to use, and by forcing developers to use "sane defaults" will help guide them. This doesn't mean to remove flexibility of the Miden client, but instead to help guide new developers. I think Miden Assembly is more or less easy to use, but it's the setup required to run MASM code which is difficult.
3) Remove the need for feature flags for default use of miden client
Developers should be able to run
cargo add miden-clientand then in theirsrc/main.rsfile have it look like this:The
cargo.tomlfile would look like this with no feature flags turned on for the Client.Currently this is how the client import looks like in a basic Miden project:
4) Better error message handling from the node and client
When submitting a transaction via the Client to the node which the node reverts, this error message is not returned to the Client.
The method
submit_transaction()should return a type that has the status / error message associated with why the transaction reverted on the node:This code does not fail, and returns a successful result even if the node rejects the tx:
Here is a concrete example of a transaction that is successful, but the node rejects:
https://github.com/partylikeits1983/miden-clob-designs/blob/84d8e52d88a4659daaaa63e1db8d51100711ef6f/tests/account_sig_check_update.rs#L195
Conclusion and final thoughts
The Miden client is an amazing technical feat and is an extremely high quality Rust repository. However, there room for improvement to lower the bar to entry for developers getting started with Miden.
The Miden rust Client will most likely become an integral part of the test harness that the compiler team @bitwalker and @greenhat are working on. Additionally the Miden node could / should be integrated into the test harness to be able to spin up a lightweight test blockchain where users can run integration tests.
Please feel free to add any thoughts / ideas of ways to make the client easier and more intuitive to use.
All reactions