Skip to content

Instantly share code, notes, and snippets.

@joshstevens19
Forked from nivida/Web3-CLI.md
Last active December 20, 2018 18:57
Show Gist options
  • Save joshstevens19/dcb8d138c330ba25934410815a61f90a to your computer and use it in GitHub Desktop.
Save joshstevens19/dcb8d138c330ba25934410815a61f90a to your computer and use it in GitHub Desktop.
Web3 CLI specification (draft)
These are the web3 commands:
  
  Starting with a project:
    init <--browser|--server|--server-api> [options]      Starts the setup, will then ask questions like NPM does (name of project etc).
                                                          Will create a basic web or node app for them.
    
    options: 
         --browser
         --server
         --server-api - could hook into express and generate them a entire boilerplate node API?
        
  Development commands:
    run       Starts a node and the project or serves them the browser if they 'init --browser'
    
  Authenticatation - login to the CLI to do authenticated tasks
    web3 login <private-key>                 Login to your eth account
    web3 logout                              Logout the authenticated account
    web3 create [entropy]                    Creates a new account with the CLI
    
  Account - manage authenticated accounts in the CLI (throwing some ideas out)
    web3 wallet create [entropy]             Generates one or more accounts in the wallet. 
                                        If wallets already exist they will not be overridden.          
    web3 wallet add <privatekey>             Adds an account using a private key or account object to the wallet.
    web3 wallet rm <index>               Removes an account from the wallet.
    web3 wallet clear                        Securely empties the wallet and removes all its accounts.
    web3 wallet encrypt <password>
    web3 wallet decrypt 
    web3 wallet load <password> 
    web3 wallet ls
  
  EthPM managment:
    web3 ethpm publish <packageName>               Adds a contract package to the current project
    web3 ethpm uninstall <packageName>             Removes a contract package to the current project
    web3 ethpm update <packageName>                Updates a contract package to the current project
                                        (could just use publish all the time)
    web3 ethpm ls                                  Lists the contract packages in the current project
    web3 ethpm install                             Install all ethpm packages
    web3 ethpm install [<packageName>[@version]>   Installs a ethpm package to the current project
    web3 ethpm owner ls <packageName>              See who the owner(s) of the package is
    web3 ethpm owner change <privatekey>           Change the owner of a package (only work if you sign it) 
                                        and only work if you authenticated with the CLI
    
  ENS management:
    web3 ens registry                           Returns the network specific ENS registry
    web3 ens resolver <ENSName>                 Returns the resolver contract to an Ethereum address.
    web3 ens owner <ENSName>                    Returns the owner of the ens domain
    web3 ens owner change <ENSName> <address>   Sets the address of an ENS name in his resolver.
    
    
  Generating of code (generate:*):
    web3 generate <tool> [options]           Generates certain files depeneding on the tool
    
    Ideas:
      web3 generate <contract>               Generates a contract class based on the contract abi
      web3 generate <sign> [sign|sign-transaction|send-sign-transaction] - Generates a code basic class with code examples
      web3 generate interface 
      web3 generate class
      web3 generate enum
      web3 generate types <ABI>              Generate full typings for a ABI
      web3 generate code <ABI>               Generate classes for the code ?? pretty neat idea! 
      .. surely we will discover move on the way! 
      
  Call a JSON-RPC method:
    web3 jsonrpc <network> <version> <method> [<params>] <id>    Calls an JSON-RPC method
    
 Contract calls: 
    web3 contract <method> [params] call [<required-options>]    Calls an contract method based on the current project (maybe json interface is defined in the package.json or something, so we don't have to ask for it everytime) ?
    web3 contract <method> [params] send [<required-options>]    send using 
    web3 contract <method> estimateGas [<required-options>]  
    web3 contract <method> encodeABI [<required-options>]  
    web3 contract events ls                                     List all events for the contract
    web3 contract events ls --past                              List only past events for a contract
    
    
  Open documents 
     web3 doc <package | keyword>  Open document to the package and what it does
     
  Version:
    web3 version                    Outputs web3 CLI version. 
    
  Alias:
    web3 alias add  ..  Add your own alias mappings for the CLI
    web3 alias rm  ..   Remove your alias mappings
    
  Star:
    web3 stars                    Returns all the things you have starred
    web3 star doc <name> <url>    Star a documentation so you can easily get back to it
   .. maybe other things we can star?
   
  ping:
    web3 ping <network|customrpc>          Check if network is alive
    
  deploy??!:
    Do we want to hook in auto deployment or here? basically doing the hard lifting in truffle and allowing ease of deployment, with a single CLI tool?

  ... think we can do cool things like `web3 audit` to audit code to try to make sure its secure as well. Probably for v2.
    

Starting with a project:

Init

  • Which "runtimes" should it support (node.js, angular, react, vue.js, ...) - (Josh: think the CLI should be built in node we can use npm to deploy it and make it install globally for users. Users are use to this experience so i think it makes sense. Stuff like commander etc can help us create a lovely CLI design).
  • Do we want to use yeoman for the setup?
  • What are the setup steps? - (Josh: npm install web-cli -g)
  • Which options will this command have? - (Josh: put my suggestions above)

Development commands

Open questions
  • Should it have the possibility to select a node type (parity, geth, ganache, ...) (Josh: maybe could be nice)

run

  web3 run --watch --net="dev"
Options
watch
  • Build on file change (wrapper of framework cli) (Josh: yeah like how angular do it, on changing a file it rebuilds. Defo worth having)
net
  • Select the node to connect

build

  web3 build --browser --node
Options
browser
  • Creates a build with the browser config
node
  • Creates a build with the node config

Package managment (powered by EthPM)

Open questions
  1. Do we want a ethpm.json as truffle has or do we just extending the package.json of npm? (Sam: I would just extend the package.json) (Josh: After looking at the package.json below i think we should have our own json file 'web3-cli.json' like angular do)
  2. Which additional options should the command add have?

add

  web3 add mypackage@1.2.1 --save
  > Package mypackage@1.2.1 would be added to the package.json.
  > Package mypackage@1.2.1 successfully added.
Options
packageName
  • <package name>@<version>

remove

  web3 remove MYPackage
  > Package with name MYPackage removed.    

(Josh: probs would go with rm to follow npm linux CLI style)

Options
packageName
  • The EthPM package name

Generating of code (generate:*)

contract

  web3 generate:contract <packageName|--abi|--address> --out --types
  > Contract with name TestContract created in PATH.    
Options
packageName (optional)
  • The EthPM package name
abi (optional)
  • The root of the path should be the project folder root (e.g. "./assets/ContractABI").
out (optional)
  • Default path is "./"
  • The root of the path should be the project folder root (e.g "./contracts/").
address (optional)
  • The contract address or an ENS name to a contract
types
  • Generates a TypeScript interface from the ABI. (Josh: This is a brilliant idea, i mentioned this above as well, defo something we should include, i was also thinking we could generate a entire class of their funtionalty written in JS or TS, we could easily define a base line app for them based on the ABI?)

Call a JSON-RPC method:

method

  web3 method <methodName: eth:*, shh:*, ...>  <options: methodParameters>
  > '0x0'

(Josh: Put my ideas above think we should have a generic one i.e. jsonrpc [] . I also think we should handle 'send' 'estimateGas' etc within calling methods for a contract)

Options
methodName
  • All methods defined in namespaces (e.g. eth:call)
options
  • How should the JSON-RPC method parameters are given to the method? (Josh: have to work out the most elegant way for this as we wouldnt want to command to get complex)

CLI configuration

The post install hook of npm should be used to installing the contract dependencies.

  //... package.json (Josh: probs best to put this in its own json file after looking at this, 'web3-cli.json' like angular do)
  {
    "web3": {
      "build": {
        "browser": {
            provider: ["metamask", "mist", "status", "brave"] // ["ws:168.111.0.1:8564"]
        },
        "node": {
            provider: "ws:168.111.0.1:8564"// IPC_PATH | http://
        }
      },
      "mainnet": {
          provider: "ws:168.111.0.1:8564" // IPC_PATH | http://
      },
      "development": {
          "net": "ganache", // ["geth", {protocol: 'HTTP', ...}]
          "truffle": false, // If true truffle will be used for the deploying of the contracts 
          "rootDir": "./",
          "packages": "./node_modules/"
      },
      "dependencies": {
          "myContractPackage": "^0.1.0",
          "myChainContractPackage: "0x0",
          "myENSNameContractPackage: "contract.eth"
      }
    }
  }
@nivida
Copy link

nivida commented Dec 12, 2018

init <--browser|--server|--server-api> [options]

I would not have these options here because they are steps in the setup:

Which runtime?
[ ] Angular
[ ] React
[ ] Node 
....

Starts a node and the project or serves them the browser if they 'init --browser'

This should be kept as simple as before:

Starts an ethereum node and the project.


Authentication

I think the Auth commands should be together with the wallet command. I would also add a wallet list command to show all accounts.


I would use namespaces for the commands because we have name conflicts for the commands.
For example: web3 ens:owner --change|--c


Generating of code (generate:*):

I would like to have the syntax of them like this: web3 generate:contract ...
Are these commands really required I think generate:contract is enough:

generate interface 
generate class
generate enum
generate types <ABI>

What exactly should this do? generate code


jsonrpc []

I would like this more:

web3 method eth:getBalance --dev --address="0x0" --block="latest"

Contract calls

On send or call could also be a setup shown:

From which address?:
> '0x0'
GasPrice:
> 100

I would define it like this:

 Contract calls: 
    contract <packageName|path to abi> <method> [params] --call/--send [options] 
    contract <packageName|path to abi> <method> [params] --estimateGas [options] 
    contract <packageName|path to abi> <method> [params] --encodeABI [options]  
    contract <packageName|path to abi> ls                                     List all events and method of the contract
    contract <packageName|path to abi> ls --methods                  List all methods of the contract
    contract <packageName|path to abi> ls --events                      List all events of the contract
    contract <packageName|path to abi> watch <eventName> --address="" --topics="" --fromBlock="" --toBlock="" --filter=""
    contract <packageName|path to abi> watch --all --address="" --topics="" --fromBlock="" --toBlock="" --filter=""

Version

This should output all installed ethereum node versions, web3 version, solc version and the angular/react version.


Alias

I would not add such a command to the cli. (alias is a default unix command)


Star

I would not add such a command to the cli.


Ping

I would not add such a command to the cli. (ping is a default unix command)


Deploy

I would not add such a command to the cli the deployment should be done by the developer it self.


Audit

This is a nice idea but I would not add it because of the responsibilities web3 will have with this command. I think it would need a security team to provide something like this that audits all the packages on ethPM and for writing some analyzing tools.

@nivida
Copy link

nivida commented Dec 12, 2018

(Josh: probs best to put this in its own json file after looking at this, 'web3

yes we could create an web3.json config file

@nivida
Copy link

nivida commented Dec 12, 2018

(Josh: think the CLI should be built in node we can use npm to deploy it and make it install globally for users. Users are use to this experience so i think it makes sense. Stuff like commander etc can help us create a lovely CLI design).

Yes for creating a CLI. But which frameworks (Angular, React etc.) do we support. That means which kind of project types can I generate with the web3 init command.

@nivida
Copy link

nivida commented Dec 12, 2018

(Josh: probs would go with rm to follow npm linux CLI style)

πŸ‘

@joshstevens19
Copy link
Author

joshstevens19 commented Dec 12, 2018

Yes i agree with you - I would not have these options here because they are steps in the setup:. I meant more we need the user to pick which runtime as per you said now πŸ‘

I think the Auth commands should be together with the wallet command. I would also add a wallet list command to show all accounts.

Yes i thought i put wallet ls but must of missed it, added it now. In terms of authentication what are you thinking like

web3 wallet login
web3 wallet logout ?

I would use namespaces for the commands because we have name conflicts for the commands.

Yes i was just defining sub-commands so for example ens would be

web3 ens owner <ENS>

and ETHpm would be

web3 ethpm owner ls <packageName>

What exactly should this do? generate code

This would generate some JS/TS code to call the contract methods for example if you had a ABI like this

{
"abi": [
        {
            "constant": true,
            "inputs": [],
            "name": "exampleAbiCall",
            "outputs": [
                {
                    "name": "exampleOutput",
                    "type": "string"
                }
            ],
            "payable": false,
            "stateMutability": "pure",
            "type": "function"
        }
   ]
}

we can then generate a class for them based on their ABI like:

export class ExampleAbiGenerated {
     public async exampleAbiCall(): Promise<string> {
          return await myContract.methods.exampleAbiCall();
     }
     // rest of functions get defined
}

Think something like this would be super awesome and powerful. Yes they would need to define myContract but generating entire code classes from ABI would be super cool. They can be updated by running it again if their ABI ever changes. We can also add a CLI command that validates the code against the ABI, the validation probably would be a v2 thing.

web3 method eth:getBalance --dev --address="0x0" --block="latest"

I see no reason why we cant support both i was thinking with my jsonrpc <network> <version> <method> [<params>] <id> was allowing people to be able to quick JSON-RPC calls without opening postmode or using curl in the command line. Think it would be a nice feature. Like if they wanted to use debug_traceTransaction method or something? but happy to put all that functionality in web3 methods πŸ˜„

On send or call could also be a setup shown:

From which address?:
'0x0'
GasPrice:
100` - Yes that would be nice for this!

Alias - I would not add such a command to the cli. (alias is a default unix command)

Alias is in git npm most package managers it allows them to make custom commands. I think it be super useful for teams to be able to share these alias. I always create them with git to do complex git commands with 1 step. Imagine them creating their own web3 deploy which under the hood ran tests and did loads of stuff, this would be possible if we set up aliases.

Star - I would not add such a command to the cli. - Happy to leave this one out more of a npm thing.

Ping - I would not add such a command to the cli. (ping is a default unix command) - i think allowing them to ping the health of the network is a positive thing and would be super easy.

Deploy - I would not add such a command to the cli the deployment should be done by the developer it self. - More of a discussion topic we could combine truffle into the web3-cli but maybe that's a v2 thing. Just trying to make web3-cli the only thing someone has to install to be able to everything in the Ethereum space (build, test. deploy)

Audit - This is a nice idea but I would not add it because of the responsibilities web3 will have with this command. I think it would need a security team to provide something like this that audits all the packages on ethPM and for writing some analyzing tools. - yep i agree was more of a topic to maybe not forget as this could be really good if done well.

Yes for creating a CLI. But which frameworks (Angular, React etc.) do we support. That means which kind of project types can I generate with the web3 init command. - AHHH ok i think we got to support a boilerplate for angular, react, native web-page and maybe node with express API? we can use their CLI to make this super easy, what do you think?

yes we could create an web3.json config file - πŸ‘

@nivida
Copy link

nivida commented Dec 12, 2018


Yes for creating a CLI. But which frameworks (Angular, React etc.) do we support. That means which kind of project types can I generate with the web3 init command. - AHHH ok i think we got to support a boilerplate for angular, react, native web-page and maybe node with express API? we can use their CLI to make this super easy, what do you think?

Hmm, this gives a lot of work to support so many projects.
Maybe it would be smarter to have the following options:

  1. Angular
  2. React
  3. Plain webpack setup with a simple index.js and index.html file.

The webpack setup should just be a plain JS/HTML project boilerplate.
Things like express or other dependencies could then be added manually.


Deploy - I would not add such a command to the cli the deployment should be done by the developer itself. - More of a discussion topic we could combine truffle into the web3-cli but maybe that's a v2 thing. Just trying to make web3-cli the only thing someone has to install to be able to everything in the Ethereum space (build, test. deploy)

The deployment of the contracts should be an easy thing to implement with web3 itself but I think that would be something for version 2.


Ping - I would not add such a command to the cli. (ping is a default unix command) - I think allowing them to ping the health of the network is a positive thing and would be super easy.

Yes, but just a ping to a node could be done over the normal CLI tools. I think a command like this web3 node --info for showing all possible information about the connected node would be a nice to have but it's currently not a must have.


Alias - I would not add such a command to the cli. (alias is a default unix command)

Alias is in git npm most package managers it allows them to make custom commands. I think it be super useful for teams to be able to share these alias. I always create them with git to do complex git commands with 1 step. Imagine them creating their own web3 deploy which under the hood ran tests and did loads of stuff, this would be possible if we set up aliases.

Yes but I think the same things are possible with shell scripts I don't why but I don't like this.


I see no reason why we cant support both i was thinking with my jsonrpc [] was allowing people to be able to quick JSON-RPC calls without opening postmode or using curl in the command line. Think it would be a nice feature.

Yes, I agree with you. We mean the same in the end just with an other syntax.
I think something like this would be the simplest way to interact:
web3 eth:getBalance <arguments>

Like if they wanted to use debug_traceTransaction method or something? but happy to put all that functionality in web3 methods

Because it's a thing of some minutes to implement a method.
Will I just implement all RPC methods in web3.


What exactly should this do? generate code

This would generate some JS/TS code to call the contract methods for example if you had a ABI like this
... - code
we can then generate a class for them based on their ABI like:
... - code
Think something like this would be super awesome and powerful. Yes they would need to define myContract but generating entire code classes from ABI would be super cool.

That's what I thought would web3 generate:contract should do :-)


They can be updated by running it again if their ABI ever changes. We can also add a CLI command that validates the code against the ABI, the validation probably would be a v2 thing.

This is a great idea!
Something like this maybe:web3 contract:check-interface --address="" πŸ€”


I would use namespaces for the commands because we have name conflicts for the commands.

Yes i was just defining sub-commands so for example ens would be

web3 ens owner

and ETHpm would be

web3 ethpm owner ls

What do you mean to a syntax like this for the namespaces?:

web3 command:action // instead of:
web3 command action

I think the Auth commands should be together with the wallet command. I would also add a wallet list command to show all accounts.

Yes I thought I put wallet ls but must of missed it, added it now. In terms of authentication, what are you thinking like

web3 wallet login
web3 wallet logout

Yes, I would simply that. It could also be web3 accounts login & web3 accounts ls etc.


Yes I agree with you - I would not have these options here because they are steps in the setup: I meant more we need the user to pick which runtime as per you said now

We should have these possibilities to configure/go through the setup with web3 init:

  1. Starts the setup and you can call a demo project without further steps (for quickly getting introduced with the development of a dapp)
  2. Starts the setup and you can call the custom project
    Steps:
    1. Node|Angular|React|...
    2. package.json information (name etc.)
    3. Ganache|Parity|Geth and options
    4. ?
  3. Run init with --demo for creating a demo project without the setup
  4. Run init with <option> for creating a custom project

Ideas:

We should also have a command :
web3 add web3-module-aragon

With the AbstractWeb3Module and AbstractContract it would be easy to implement well known smart contracts protocols as a web3-module.
The contracts dependencies for this could be managed with ethPM and for example the web3-module-aragon code normally with npm.


@joshstevens19
Copy link
Author

joshstevens19 commented Dec 13, 2018

The webpack setup should just be a plain js/html project boilerplate.
Things like express or other deps could then be added manually.

Ok yeah i agree, we need to support a simple 3 and if people want to help out or the demand is needed we add it then πŸ‘Œ

The deployment of the contracts should be an easy thing to implement with web3 it self but I think that would be something for version 2.

Ok perfect fine with me!

Yes, but just a ping to a node could be done over the normal cli tools. I think something like an web3 node --info for showing all possible information about the connected node would be a nice to have but it's currently not a most have.

I like that web3 node <network|customrpc> --info something along those lines, again this can fall lower on priorities!

Yes but I think the same things are possible with shell scripts I don't why but I don't like this.

What's the reasons for this? I think alias are a must for allowing users to define their own commands, it gives flexibility, without the feature in git i would be repeating myself a million times. Lets maybe discuss this further, il be interested in why you don't like it? Making the user have to write shell scripts to sort it seems a bit annoying. If i wanted to make a command which checked the health of the node and then executed a command i would want to be able to quickly add it as alias in the CLI for quick executing.

Yes, I agree with you. We mean the same in the end just with an other syntax.

Perfect

Because it's a thing of some minutes to implement an method.
Will I just implement all RPC methods in web3.

As long as its super flexible and can handle all RPC + custom RPC methods and custom RPC networks then fine with me πŸ‘

Thats what I thought would web3 generate:contract should do :-)

Ok cool thinking the same things again but in a different command, perfecto πŸ‘

This is a great idea!
Something like this maybe:web3 contract:check-interface --address=""

yeah something along those lines, where they can check 1 interface or do wild cards to validate a few. In theory if they just wanted to validate the whole application if they supply us the ABI we can check anything which has .methods. and grab the exampleAbiCall (function name) try to find it in ABI then validate params + output. We could also have a ignore like //web3:validation-ignore-line if they ever call something else .methods... something like that would be cool.

What do you mean to a syntax like this for the namespaces?:

yeah i think we should follow the git and npm way they designed their CLI

web3 command action πŸ˜„

web3 command:action feels unnatural and wrong in my eyes.

Yes, I would simply that. It could also be web3 accounts login & web3 accounts ls etc.

Yeah ok as long as we agree that it comes under the same command that's fine. I like wallet as it goes hand in hand with the cryto space but again i'm easy.

We should have these possibilites to configure/go through the setup with web3 init:

  1. Starts the setup and you can call a demo project without further steps (for quickly getting intoduced with the development of a dapp)
  2. Starts the setup and you can call custom project
    Steps:
    1. Node|Angular|React|...
    2. package.json informations (name etc.)
    3. Ganache|Parity|Geth and options
    4. ?
  3. Run init with --demo for creating a demo project without the setup
  4. Run init with <option> for creting a custom project

npm do something like this

npm init react-app ./my-react-app

so we could have the same for fast entry if not they do web3 init and you choose like npm does. This can generate the web3.json metadata by them entering important info like version, name etc! Think after step 3 we stop as we want the web3 init to be simple and quick to do.

We should also have a command : web3 add web3-module-aragon

That's a great idea πŸ‘

Ideas:

We can also allow you to be able to use web3 methods directly in the CLI like normal i.e.

web3 execute new web3.utils.isHex('0xc1912'); or
web3 execute <file> [--network=mainnet] or
web3 execute web3.eth.getBlockNumber() [--network=mainnet] - defaults to mainnet

All of these will create a web3 instance for them and execute the command within the CLI, allowing them to combine commands together to see the result by just using the CLI or even just wanting to execute a util method for information. It will be quite nice, if you are quickly on the fly want to convert your number to a hex but your on another project without web3 installed, in your CLI you can quickly execute it as it's installed globally.

web3 execute web3.utils.toHex('234');
> "0xea"

@nivida
Copy link

nivida commented Dec 20, 2018

Will write the result down of this discussion in my gist and reference you @joshstevens19.

Note:
I think a big target is not to reinvent the wheel for everything. Because there are many existing tools we could just integrate.
https://github.com/ethereum-ts/TypeChain
https://github.com/trufflesuite/truffle
https://github.com/nomiclabs/buidler
https://www.npmjs.com/package/commander
https://www.npmjs.com/package/yo
...

@joshstevens19
Copy link
Author

Once you done that i will create us a professional google doc and we go from there πŸ‘

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment