o1-labs / zkapp-cli

CLI to create a zkApp (zero-knowledge app) for Mina Protocol
https://docs.minaprotocol.com/zkapps/how-to-write-a-zkapp
Apache License 2.0
115 stars 44 forks source link

extend scaffolding examples #259

Closed Trivo25 closed 2 years ago

Trivo25 commented 2 years ago

discuss potentially adding scaffolding for some popular frameworks/setups (e.g. React, Vue, ..) to make it easier for devs to integrate their smart contracts into an UI project

mitschabaude commented 2 years ago

Some ideas:

jasongitmail commented 2 years ago

I really like this.

We could add --sveltekit, --nextjs, --vue, & --monorepo and initialize the projects using their init commands (e.g. npm create svelte@latest ui, npx create-next-app@latest ui , etc) or --monorepo creates an empty ui directory for the dev to put what they want in it.

This way our maintenance is reasonably low.

// `zk project <name>` creates:

name/
  ui/
  contracts/

Note: This also requires:

  1. an update to the zk file command to always create files inside within /contracts/src if it's a monorepo or inside src/ as currently does if not a mono repo, which is doable.
  2. moving the Github actions dir to the root
  3. possibly others
jasongitmail commented 2 years ago

Which user experience would you all prefer? @mitschabaude @Trivo25 @ymekuria @MartinMinkov @bkase


1.) Command:

zk project foo --svelte

Help menu:

❯ zk project --help zk project [name]

Create a new project

Options: --svelte, --sveltekit Creates an accompanying SvelteKit UI [boolean] --next, --nextjs Creates an accompanying NextJS UI [boolean] --vue, --vuejs Creates an accompanying VueJS UI [boolean] -h, --help Show help [boolean] -v, --version Show version number [boolean]


2.) Command:

zk project foo --ui svelte

Help menu:

❯ zk project --help
zk project [name]

Create a new project

Options: --ui Creates an accompanying UI [string] [choices: "svelte", "next", "vue"] -h, --help Show help [boolean] -v, --version Show version number [boolean]


The 2nd can be implemented a bit DRYer and feels more "correct", but is more to type for the user. The first may be easiest to remember. (It is possible to make the user's choices mutually exclusively in both cases, so they would behave identically. It's just a matter of what command we want and what we want the help menu to look like.)

ymekuria commented 2 years ago

@jasongitmail I love the direction this is going. I prefer the 2nd command even though it's more verbose, because it is clearer that a user is creating a project with a UI included. If a user enters zk project foo --ui, we could display all the available framework options for them to select, similar to how a user can select which alias to deploy to when entering zk deploy without entering the alias in the command.

MartinMinkov commented 2 years ago

I like the second one as well. It feels more intuitive to use, and for a CLI argument that can have multiple values, it feels better to specify it under a single option with a meaning that is easy to remember.

jasongitmail commented 2 years ago

Cool. I put together a working version of this for Svelte, NextJS, & Vue. Took a bit of refactoring and needs more clean up and a lot more thinking through and testing.

I'll push a branch and open a PR so we can play with it.

bkase commented 2 years ago

I think we should ask this by default. Most people will want a UI — I think if you omit the —ui then there is a prompt asking you which one you want (with none as an option too)

ymekuria commented 2 years ago

Should we support a create react app version also? I personally prefer NextJS for React projects, but some devs may not. What does everyone think? This could be an addition further down the road if we get requests for it.

With this option, it will now be easy for devs to add their contracts into a UI directly through a file path. The question we should discuss and answer is what pattern we should recommend. 1) Add UI directly through a file path or 2) Publish to npm and import into the UI

The first option is definitely easier and will have less friction for devs. We could even add a very basic UI with a contract and the mina provider connected into the template.

bkase commented 2 years ago

Agreed 100% , we should support create react app in addition to next

mitschabaude commented 2 years ago

This has taken a great direction! I'd also still like the --monorepo flag to enable the long tail of ui setups which we don't support, or maybe add "empty" as an option to the --ui flag for getting a monorepo setup with an empty ui folder. This is what I'd personally use I guess.

mitschabaude commented 2 years ago

With this option, it will now be easy for devs to add their contracts into a UI directly through a file path. The question we should discuss and answer is what pattern we should recommend.

1. Add UI directly through a file path or

2. Publish to npm and import into the UI

Definitely the first option! Publishing to npm has independent value for composability and visibility, but is not reasonable as a dev experience when iterating on a UI. Also we should stop recommending "npm link", in favor of the monorepo setup with a local import

What we could do is make the zkapp package name resolve to the local folder, so devs can use the same import as if it was coming from npm / npm link

jasongitmail commented 2 years ago

maybe add "empty" as an option to the --ui flag

That's the approach I landed on too. 👍

WIP PR to play with. A dev can use any of these commands:

zk project foo
zk project foo --ui svelte     // SvelteKit
zk project foo --ui next        // NextJS
zk project foo --ui vue         // VueJS
zk project foo --ui empty    
zk project foo --ui unsupported // shows user an error to select from one of supported choices

WIP. Tests need to be fixed and there are a few improvements I'd want to add, like a good monorepo README. But this works to try it out. It could be further improved if all UI options allowed passing flags b/c I'd want to automatically add Prettier and ESLint to the UI project too.

I did NOT update the zk file command, so a dev would need ot be in their contracts dir, if using a monorepo for it to work. I want to give this more thought. Anybody want that command to work in the monorepo root? We could support that, but I currently envision people to be cd'd into the project they're working on.

Definitely the first option! Publishing to npm has independent value for composability and visibility, but is not reasonable as a dev experience when iterating on a UI. Also we should stop recommending "npm link", in favor of the monorepo setup with a local import

What we could do is make the zkapp package name resolve to the local folder, so devs can use the same import as if it was coming from npm / npm link

To be explored still

MartinMinkov commented 2 years ago

For scaffolding a UI, are we just creating the UI project for the user or are we additionally modifying the scaffolded UI to be ready for use with SnarkyJS right away? If we are doing the latter, there are a few steps that should be included to make sure that someone can start using their UI as seamless as possible:

  1. Set up correct headers on the server
  2. Set up a global context with SnarkyJS where appropriate(?)
  3. Auto import a scaffolded smart contract into the main page of the generated UI(?)

I'm probably missing others but we should land on either letting the user set up these details themselves or doing it for them.

jasongitmail commented 2 years ago

or scaffolding a UI, are we just creating the UI project for the user or are we additionally modifying the scaffolded UI to be ready for use with SnarkyJS right away?

I'd like to land a smaller PR first and explore these afterward. Just to control complexity and let us kick the tires on this to ensure it works as expected across systems, etc first. Some of this will veer into "stuff we have to maintain" for each platform as it changes, so we will need to figure out tests too; but it'd be very useful.

Set up correct headers on the server

This is important on the server that runs via npm run dev or similar +1 Let's create some separate issues.

jasongitmail commented 2 years ago

Agreed 100% , we should support create react app in addition to next

I'd prefer to wait on Create React App, at least until there is demand for it and then to still stop and consider if it's worth it or if people seem happy enough to just use Next. The reason is that CRA will create a less good user experience for end users than NextJS, due to CRA creating one giant JS blob. It's outdated imo

mitschabaude commented 2 years ago

Yeah I agree @MartinMinkov, setting correct headers and stuff needed to make it work should be definitely handled by us in these commands. But yeah separate PR.

I'm conflicted about the idea of adding imports of snarkyjs / the contract for the user, or setting up global state (I guess you mean stuff like isReady, Mina,setActiveInstance?). It adds complexity for us; but it could potentially give lots of devs a less bumpy start.

mitschabaude commented 2 years ago

I'd prefer to wait on Create React App, at least until there is demand for it

One data point is that Matej used CRA and had quite a bit of pain connecting it with snarkyjs, see https://github.com/o1-labs/snarkyjs/issues/385

I personally wouldn't use CRA anymore, but from my experience the fully client side rendered architecture is not necessarily ill performant if you're careful enough that the initial load is small, I like client side rendering tbh for its simplicity

ymekuria commented 2 years ago

I'm conflicted about the idea of adding imports of snarkyjs / the contract for the user, or setting up global state (I guess you mean stuff like isReady, Mina,setActiveInstance?). It adds complexity for us; but it could potentially give lots of devs a less bumpy start.

Adding the a scaffold with a modified UI will make getting started for devs much easier. I agree we should create new issues and tackle this in separate PRs. I think we can at the very least set up the headers for an MVP and move one to how to import SnarkyJS etc once we can all agree on a pattern.