Skip to content
This repository has been archived by the owner on Feb 8, 2023. It is now read-only.

Extend create-near-app to create CLI tools for smart contracts | Bounty: $2000 USD in NEAR #11

Closed
3 tasks
ilblackdragon opened this issue Jun 8, 2020 · 13 comments
Assignees
Labels
development nodejs tribe Cross-post bounty to tribe

Comments

@ilblackdragon
Copy link
Member

ilblackdragon commented Jun 8, 2020

Description

Implement a template (in Node.js) that will help smart contract developers creating a dedicated command line util for their smart contracts.

We also want to extend create-near-app tool, so CLI is optionally initialized for the app.

Context

Details are here: near/devx#207

Acceptance

  • CLI template/framework enabling fast creation of command line utils for NEAR smart contracts
  • The access keys are integrated with near-shell
  • create-near-app staking-pool asks set of questions and creates a CLI sub-project

Bounty

USD $2000 in NEAR

@ilblackdragon ilblackdragon added tribe Cross-post bounty to tribe development nodejs labels Jun 8, 2020
@jakestutzman jakestutzman changed the title Extend create-near-app to create CLI tools for smart contracts Extend create-near-app to create CLI tools for smart contracts | Bounty: $2000 USD in NEAR Jul 24, 2020
@luciotato
Copy link

I want to start working on this.

@luciotato
Copy link

@ilblackdragon, @chadoh can you assign me this issue?

@chadoh
Copy link

chadoh commented Aug 19, 2020

I think there’s some design work to be done here. Before you get started coding, @luciotato, please document here how you plan to implement this and give us a chance to have a quick discussion about it. The sorts of questions I’d like to see answered:

  • what will be the name of this CLI subdirectory?
  • how will one use this CLI tool/subdirectory?
  • as your contract changes, does each interface change require manual updates to the CLI subdirectory? (I assume yes, at this point)

To me it seems like this could turn into a research task that results in a change to near-cli, but depending on how the extension to create-near-app turns out, we may decide to not ship it at this point. Please document what you plan to deliver given that possibility, as I want to have clear expectations on both sides about what counts as fulfilling the bounty.

@luciotato
Copy link

luciotato commented Aug 20, 2020

FIRST DRAFT REPLACED BY 2ND DRAFT BELOW

Considering the example:

near call my_validator deposit '{}' --accountId user1 --amount 100
near call my_validator stake '{"amount": "100000000000000000000000000"}' --accountId user1

I would split this in two parts

Part 1:

We need a common format for the "contract interface" of NEAR smart contracts (i.e. "to solve contract medatada problem" as discussed here: near/devx#207 (comment) )

I propose to use typescript declaration files .d.ts, because:
* We're already using AssemblyScript as default for create-near-app
* typescript/javascript will bring in the most developers
* typescript is easy to read for a large number of developers
* It's very easy to extract information from .ts files (for example by using @willemneal's https://github.com/willemneal/visitor-as)
* Having the contract interface as .d.ts files makes it easier for a large number of developers to build tools for NEAR smart contracts (interface validators, fuzzers, helpers, inter-contract call validators, including a contract as dependency of another, etc)
* There are already tools that generate .d.ts files when compiling rust to wasm https://rustwasm.github.io/docs/book/game-of-life/hello-world.html

Scope: I can help by creating a node_module to generate a .d.ts file from AssemblyScript contract code, but I don't have enough experience with rust to do the same for rust contract code or to ensure the .d.ts file is generated on compilation. I need help with that.

Part 2:

  • Develop an independent module named 'create-contract-cli'. (When that module becomes stable we can integrate it into create-near-app)

  • 'create-contract-cli' will parse the contract file and create a default node-cli project with one command for each declared function

  • Usage:

    npx create-contract-cli my_validator[.d.ts]

Will create a new node-cli app dir /my_validator/ with the following usage:

npx my_validator deposit 100N

npx my_validator stake 100N

create-contract-cli will create a base/initial contract's cli app. It will be a base skeleton app, handling standard parameters. Complex parameters like nested JSON structures will be left up to the user to define. Also the user can then extend the app to include commands like:

npx my_validator deposit-and-stake 100N

The cli will read credentials from ~/.near-credentials (The access keys are integrated with near-shell)

-- END OF FIRST DRAFT

This will be the first Minimum Viable Product for create-near-cli, and I propose closing the scope of this issue/bounty on:

  • A tool to create .d.ts files from AssemblyScript contract code
  • create-contract-cli MVP, as defined in Part 2

More analysis required: Can we decorate function parameters to specify if quantities are in NEAR or YoctoNEAR? It would be nice to have and would rule out costly mistakes.

edit: syntax edit2:scratch cancelled idea

@ilblackdragon
Copy link
Member Author

@luciotato are you planning to work on this bounty?
If yes, do you need any input on our side?

I like your suggestions on "100N" vs "100yN". Also generally, I think we should use N everywhere by default.
The yoctoNEAR are right now in arguments - because those arguments are raw data going to blockchain. But CLI should wrap that for sure.

@luciotato
Copy link

@ilblackdragon I was waiting for your comments and approval. I can start working if you're OK with the plan.

@luciotato
Copy link

luciotato commented Sep 16, 2020

Ok, I'll start with this, this is the new plan:

SECOND DRAFT

Considering the example:

near call my_validator deposit '{}' --accountId user1 --amount 100
near call my_validator stake '{"amount": "100000000000000000000000000"}' --accountId user1

I would split this in two parts

Part 1:

I'll make a minimal rust parser with enough knowledge to parse a contract's src/lib.rs and extract:

  • pub fn & its parameters -- contract interface
  • pub fn comments -- for the cli --help

With the parsed info I'll create a basic cli project for the contract with the least dependencies possible

usage:

	> cd myproject/contracts/staking-pool
	> parse_and_create_cli lucky --account-id luckystaker.stakehouse.betanet 
	...parsing scr/lib.rs
	...creating ../lucky
	...creating ../lucky/index.js
	...creating ../lucky/package.json
	...cd ../lucky
	...npm link
	...done
	
	>lucky get_owner_id
	...calling luckystaker.stakehouse.betanet.get_owner_id()
	'luciotato.betanet'
	
	>lucky ping
	...calling luckystaker.stakehouse.betanet.ping()

	>lucky deposit 100N
	...calling luckystaker.stakehouse.betanet.deposit() with 100N attached

	>lucky stake 60N
	...calling luckystaker.stakehouse.betanet.withdraw({amount:60N}) 

	>lucky withdraw 40N
	...calling luckystaker.stakehouse.betanet.withdraw({amount:40N}) 

	>lucky --help
	[prints each commands+comments extracted from rust source ]

Part 2:

  • Develop an independent node_module named 'create-contract-cli'. (When that module becomes stable we can integrate it into create-near-app)

  • 'create-contract-cli' will use the parser-creator from part 1, parsing src/lib.rs and creating a default node-cli project with one command for each declared function

  • Usage:

        >cd myproject/contracts/staking-pool
	>npx create-contract-cli 
	...parsing scr/lib.rs
        Enter the account_id where the contract is deployed: luckystaker.stakehouse.betanet 
        Enter the nickname for your contract: lucky
	...creating ../lucky
	...creating ../lucky/index.js
	...creating ../lucky/package.json
	...cd ../lucky
	...npm link
	...done

create-contract-cli will create a base/initial contract's cli app. It will handle standard parameters. Complex parameters like nested JSON structures will be left up to the user to define. Also the user can then extend the app to include commands like:

lucky show stats

to schedule calls to get owner info, public staking key, staked amount, number of accounts, etc

The cli will use near call to call the contract

-- END OF SECOND DRAFT

This will be the first Minimum Viable Product for create-near-cli, and I propose closing the scope of this issue/bounty here.

edit: syntax

@luciotato
Copy link

Update: I've completed the goals of Draft#2. - I'm the phase of testing, writing docs and creating a screen-cast demo.

@luciotato
Copy link

@ilblackdragon, I've a working tool for this bounty:

Check:
https://github.com/luciotato/create-contract-cli

asciicast

@behaviary
Copy link
Contributor

@chadoh will be able to review today or tomorrow. Thanks for this submission! This does look cool!

@chadoh
Copy link

chadoh commented Oct 20, 2020

Looks cool! Nice devx. I look forward to seeing how people use this!

Some specific critiques on the approach here:

  • I see a z-old folder. Should this be removed?

  • I think most projects should avoid having build artifacts checked into the codebase. You might be able to get rid of dist and res

  • I see the --target ts item on the roadmap. How much more effort would that be? What benefit does this bring, given that this is meant to be used from a CLI and not as a dependency in a JS project?

  • I find the option to specify integers using i a bit surprising. From the README I find it hard to tell if this is yoctoNEAR or NEAR! Is it only for numbers that aren't supposed to be either? I wonder if it makes sense to require N or yN to be explicit, and to forbid raw numbers for arguments that receive NEAR amounts. Don't want people to make mistakes here! And then regular number arguments don't need a decorator.

  • Not sure I like the choice to parse a JSON-like object from the command line rather than create a more traditional CLI with options. Instead of:

     lucky get_accounts { from_index:1i limit: 10i }
    

    I think I might prefer:

     lucky get_accounts --from_index=1 --limit=10
    

    It seems like a more expectable command line interface to me.

All-in-all, I think this is a great first version, and well deserving of the bounty. Thank you! We will shout this out in the next community newsletter 😊

@chadoh chadoh closed this as completed Oct 20, 2020
@luciotato
Copy link

luciotato commented Oct 21, 2020

Hi Chad!

I see a z-old folder. Should this be removed?

Yes

I think most projects should avoid having build artifacts checked into the codebase. You might be able to get rid of dist and res

/dist can be removed once we publish this as an npm package. OTOH /res is "resources" and it's needed

I see the --target ts item on the roadmap. How much more effort would that be? What benefit does this bring, given that this is meant to be used from a CLI and not as a dependency in a JS project?

You're right, I'll remove that from the roadmap

I find the option to specify integers using i a bit surprising. From the README I find it hard to tell if this is yoctoNEAR or NEAR! Is it only for numbers that aren't supposed to be either? I wonder if it makes sense to require N or yN to be explicit, and to forbid raw numbers for arguments that receive NEAR amounts. Don't want people to make mistakes here! And then regular number arguments don't need a decorator.

Is it only for numbers that aren't supposed to be either (NEAR or Yoctos)?

Yes

The most common numeric argument type for contracts is U128/yoctos, that's why no-decorator means NEAR which in turn converts 5 to "500000000000000000000" before sending it to the contract
"i" means: send it as it is, not converted, not enclosed in quotes. Maybe we can explain it better and see what the users' feedback is?

Thank you!

@luciotato
Copy link

luciotato commented Oct 21, 2020

I rewrote most of the readme based on your suggestions

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
development nodejs tribe Cross-post bounty to tribe
Projects
None yet
Development

No branches or pull requests

4 participants