From 62ed09390569e78644fcee2940ce0a3cba2fb9d3 Mon Sep 17 00:00:00 2001 From: Jonathan LEI Date: Sun, 16 Jul 2023 08:37:01 +0000 Subject: [PATCH] docs: add documentation --- book/book.toml | 5 +++ book/src/SUMMARY.md | 24 ++++++++++- book/src/accounts.md | 62 +++++++++++++++++++++++++++ book/src/argument-resolution.md | 46 ++++++++++++++++++++ book/src/declaring-classes.md | 40 ++++++++++++++++++ book/src/deploying-contracts.md | 23 ++++++++++ book/src/installation.md | 53 +++++++++++++++++++++++ book/src/introduction.md | 5 +++ book/src/invoking-contracts.md | 59 ++++++++++++++++++++++++++ book/src/providers.md | 75 +++++++++++++++++++++++++++++++++ book/src/ref/commands.md | 36 ++++++++++++++++ book/src/shell-completions.md | 30 +++++++++++++ book/src/signers.md | 52 +++++++++++++++++++++++ book/src/title-page.md | 3 -- 14 files changed, 509 insertions(+), 4 deletions(-) create mode 100644 book/src/accounts.md create mode 100644 book/src/argument-resolution.md create mode 100644 book/src/declaring-classes.md create mode 100644 book/src/deploying-contracts.md create mode 100644 book/src/installation.md create mode 100644 book/src/introduction.md create mode 100644 book/src/invoking-contracts.md create mode 100644 book/src/providers.md create mode 100644 book/src/ref/commands.md create mode 100644 book/src/shell-completions.md create mode 100644 book/src/signers.md delete mode 100644 book/src/title-page.md diff --git a/book/book.toml b/book/book.toml index 071e572..7e96645 100644 --- a/book/book.toml +++ b/book/book.toml @@ -3,3 +3,8 @@ authors = ["Jonathan Lei"] language = "en" multilingual = false src = "src" +title = "Starkli Book" + +[output.html] +git-repository-url = "https://github.com/xJonathanLEI/starkli" +no-section-label = true diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index d4cd051..cff19d3 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -1,3 +1,25 @@ # Summary -[starkli](./title-page.md) +[Introduction](./introduction.md) + +# Getting started + +- [Installation](./installation.md) +- [Shell completions](./shell-completions.md) + +# Core concepts + +- [Providers](./providers.md) +- [Signers](./signers.md) +- [Accounts](./accounts.md) +- [Argument resolution](./argument-resolution.md) + +# Cookbooks + +- [Declaring classes](./declaring-classes.md) +- [Deploying contracts](./deploying-contracts.md) +- [Invoking contracts](./invoking-contracts.md) + +# Reference + +- [Commands](./ref/commands.md) diff --git a/book/src/accounts.md b/book/src/accounts.md new file mode 100644 index 0000000..6f6af1a --- /dev/null +++ b/book/src/accounts.md @@ -0,0 +1,62 @@ +# Accounts + +Starkli sends out transactions through accounts. Starknet natively supports [account abstraction](https://ethereum.org/en/roadmap/account-abstraction/) and all accounts are smart contracts. Therefore, there are many "flavors" of accounts and Starkli supports the most popular ones. Starkli refers to these "flavors" as _variants_. + +Currently, the only supported variant is [OpenZeppelin's account contract implementation](https://github.com/OpenZeppelin/cairo-contracts/blob/70cbd05ed24ccd147f24b18c638dbd6e7fea88bb/src/openzeppelin/account/presets/Account.cairo), but many more are expected to be supported soon. + +Accounts can be created and managed through the `starkli account` command. Variant-specific commands are available under `starkli account `. + +## Account creation + +Before creating an account, you must first decide on the _variant_ to use. As of this writing, the only supported variant is `oz`, the OpenZeppelin account contract. + +All variants come with an `init` subcommand that creates an account file ready to be deployed. For example, to create an `oz` account: + +```console +starkli account oz init /path/to/account +``` + +> ℹ️ **Note** +> +> The `starkli account oz init ` command requires a signer. Starkli would complain that a signer is missing when running the command as shown, unless a keystore is specified via the `STARKNET_KEYSTORE` environment variable. See the [signers page](./signers.md) page for more details. + +## Account deployment + +Once you have an account file, you can deploy the account contract with the `starkli account deploy` command. This command sends a `DEPLOY_ACCOUNT` transaction, which requires the account to be funded with some `ETH` for paying for the transaction fee. + +For example, to deploy the account we just created: + +```console +starkli account deploy /path/to/account +``` + +> ℹ️ **Note** +> +> This command also requires a signer. You must provide the same signer used for creating the account file in the first place. + +When run, the command shows the address where the contract will be deployed on, and instructs the user to fund the account before proceeding. Here's an example command output: + +```console +The estimated account deployment fee is 0.000011483579723913 ETH. However, to avoid failure, fund at least: + 0.000017225369585869 ETH +to the following address: + 0x01cf4d57ba01109f018dec3ea079a38fc08b789e03de4df937ddb9e8a0ff853a +Press [ENTER] once you've funded the address. +``` + +Once the account deployment transaction is confirmed, the account file will be update to reflect the deployment status. It can then be used for commands where an account is expected. + +## Account fetching + +Account fetching allows recreating the account file from on-chain data alone. This could be helpful when: + +- the account file is lost; or +- migrating an account from another tool/application. + +The `starkli account fetch` commands creates an account file using just the address provided: + +```console +starkli account fetch
--output /path/to/account +``` + +Running the command above creates the account file at `/path/to/account`. diff --git a/book/src/argument-resolution.md b/book/src/argument-resolution.md new file mode 100644 index 0000000..a4fb76d --- /dev/null +++ b/book/src/argument-resolution.md @@ -0,0 +1,46 @@ +# Argument resolution + +To make argument input easier and less error-prone, Starkli supports _argument resolution_, the process of expanding simple, human-readable input into actual field element arguments expected by the network. + +By default, arguments are only parsed as raw field elements, accepting both decimal and hexadecimal representations. + +To make arguments expandable, and thus trigger the resolution process, use the format `scheme:content`, where `scheme` is one of the supported [schemes](#schemes), and `content` is the scheme-specific content. + +## Schemes + +### `addr` + +The `addr` scheme resolves the address name provided as `content` into a full address using an _address book_ under the current network ID. As of this writing, the actual address book feature hasn't been implemented, and a hard-coded address book is used instead, which contains only one entry `eth` for the `ETH` token address. + +### `u256` + +The `u256` scheme interprets `content` as an unsigned 256-bit integer and resolves into _2_ field element arguments for the low and high 128 bits, respectively. This scheme is useful for working with contracts expecting `u256` arguments, such as the standard ERC20 contract. + +### `str` + +The `str` scheme encodes `content` as [Cairo short string](https://book.starknet.io/chapter_2/strings.html#working_with_short_strings). + +### `const` + +The `const` scheme uses `content` as the key to look up a hard-coded table to commonly used constant values. The current list of constants are: + +| Key | Value | +| ---------- | ------------------------------------------------------------------------ | +| `u256_max` | `0xffffffffffffffffffffffffffffffff, 0xffffffffffffffffffffffffffffffff` | +| `felt_max` | `0x0800000000000011000000000000000000000000000000000000000000000000` | + +## Scheme omission + +Normally, the `scheme:` prefix is required for opting in to argument resolution. However, there's one exception: the `addr:` prefix can be omitted when an address is expected. + +As an example, consider the `starkli invoke` command. To use the `addr` scheme, one would run: + +```console +starkli invoke addr:eth ... +``` + +However, since the first positional argument for the `starkli invoke` is always expected to be an address, this command can be simplified into: + +```console +starkli invoke eth ... +``` diff --git a/book/src/declaring-classes.md b/book/src/declaring-classes.md new file mode 100644 index 0000000..d361b45 --- /dev/null +++ b/book/src/declaring-classes.md @@ -0,0 +1,40 @@ +# Declaring classes + +In Starknet, all deployed contracts are instances of certain declared classes. Therefore, the first step of deploying a contract is declaring a class, if it hasn't been declared already. + +With Starkli, this is done with the `starkli declare` command. + +> ℹ️ **Note** +> +> You need both a [signer](./signers.md) and an [account](./accounts.md) for this. The commands shown in this page omit the signer and account options for better readability, and assume you've properly configured the environment variables. + +You can declare the following types of contract artifacts: + +- Sierra classes: output of the `starknet-compile` command; and +- _(Deprecated)_ Legacy Cairo 0 classes: output of the `starknet-compile-deprecated` command + +To declare any class, simply run: + +```console +starkli declare /path/to/class/file +``` + +Starkli is capable of determining the type of class provided. There are no separate commands for Sierra and legacy classes. + +Once the declaration is successful, Starkli displays the class hash declared. The class hash is needed for [deploying contracts](./deploying-contracts.md). + +## Sierra class compilation + +When declaring Sierra classes, Starknet requires a so-called _CASM hash_ to be provided. This is important because as of this writing, the Sierra-to-CASM compilation process isn't proven by the OS. Should the _CASM hash_ not be provided and signed by the user, a malicious sequencer would be able to claim anything to be the CASM output, effectively deploying arbitrary code. + +To come up with the _CASM hash_, Starkli compiles the Sierra class provided under the hood. By default, it automatically chooses one of the compiler versions shipped with Starkli itself based on the network. Users can override the compiler version used by providing a `--compiler-version ` option. + +> ℹ️ **Note** +> +> Unless you're working with custom networks where it's infeasible for Starkli to detect the right compiler version, you shouldn't need to manually choose a version with `--compiler-version`. +> +> If Starkli _does_ choose the wrong compiler version, try upgrading Starkli, or file a bug if you're already on the latest release. + +> ℹ️ **Note** +> +> For advanced users, it's possible to skip the Sierra-to-CASM compilation process by directly providing a `--casm-hash `. diff --git a/book/src/deploying-contracts.md b/book/src/deploying-contracts.md new file mode 100644 index 0000000..59f47a4 --- /dev/null +++ b/book/src/deploying-contracts.md @@ -0,0 +1,23 @@ +# Deploying contracts + +Once you obtain a class hash by [declaring a class](./declaring-classes.md), it's possible to deploy instances of the class. + +With Starkli, this is done with the `starkli deploy` command. + +> ℹ️ **Note** +> +> You need both a [signer](./signers.md) and an [account](./accounts.md) for this. The commands shown in this page omit the signer and account options for better readability, and assume you've properly configured the environment variables. + +To deploy a contract with class hash ``, simply run: + +```console +starkli deploy +``` + +where `` is the list of constructor arguments, if any. + +> 💡 **Tips** +> +> You might be able to leverage [argument resolution](./argument-resolution.md) to simplify the argument list input. + +Under the hood, Starkli sends an `INVOKE` transaction to the [Universal Deployer Contract](https://community.starknet.io/t/universal-deployer-contract-proposal/), as Starknet does not support native external contract deployment transactions. diff --git a/book/src/installation.md b/book/src/installation.md new file mode 100644 index 0000000..5b3c0b5 --- /dev/null +++ b/book/src/installation.md @@ -0,0 +1,53 @@ +# Installation + +The easiest way to install Starkli is to use `starkliup`, a portable script that downloads prebuilt binaries and manages shell configuration for you. However, it might not be available depending on your device's platform and/or architecture. + +Note that if you use any installation method other than `starkliup`, you will need to manually [set up shell completions](./shell-completions.md). + +## Using `starkliup` + +If you're on Linux/macOS/WSL, you can install `stakrliup` by running the following command: + +```console +curl https://get.starkli.sh | sh +``` + +You might need to restart your shell session for the `starkliup` command to become available. Once it's available, run the `starkliup` command: + +```console +starkliup +``` + +Running the commands installs `starkli` for you, and upgrades it to the latest release if it's already installed. + +`starkliup` detects your device's platform and automatically downloads the right prebuilt binary. It also sets up shell completions. You might need to restart your shell session for the completions to start working. + +> ℹ️ **Note** +> +> Over time, `starkliup` itself may change and require upgrading. To upgrade `starkliup` itself, run the `curl` command above again. + +## Prebuilt binaries + +Prebuilt binaries are available with [GitHub releases](https://github.com/xJonathanLEI/starkli/releases) for certain platforms. + +Prebuilt binaries are best managed with [`starkliup`](#using-starkliup). However, if you're on a platform where `starkliup` isn't available (e.g. using `starkli` on Windows natively), you can manually download the prebuilt binaries and make them available from `PATH`. + +## Install from source + +If you have [Rust](https://www.rust-lang.org/) installed, it's also possible to install `starkli` directly from source. Installing from source might be necessary if you want to use an unreleased feature, for example. + +> ℹ️ **Note** +> +> Shell completions would _not_ be configured when you install `starkli` from source. You need to manually [set up shell completions](./shell-completions.md) for it to work. + +To install from source from [crates.io](https://crates.io/crates/starkli): + +```console +cargo install --locked starkli +``` + +Alternatively, to install from [GitHub](https://github.com/xJonathanLEI/starkli): + +```console +cargo install --locked --git https://github.com/xJonathanLEI/starkli +``` diff --git a/book/src/introduction.md b/book/src/introduction.md new file mode 100644 index 0000000..a9fce18 --- /dev/null +++ b/book/src/introduction.md @@ -0,0 +1,5 @@ +# Welcome to Starkli + +Starkli is a command line tool for interacting with [Starknet](https://starknet.io/), powered by [starknet-rs](https://github.com/xJonathanLEI/starknet-rs). + +Starkli allows you to query Starknet and make transactions with ease. It's fast, easy to install, and intuitive to use. diff --git a/book/src/invoking-contracts.md b/book/src/invoking-contracts.md new file mode 100644 index 0000000..2a35a41 --- /dev/null +++ b/book/src/invoking-contracts.md @@ -0,0 +1,59 @@ +# Invoking contracts + +With Starkli, this is done with the `starkli invoke` command. + +> ℹ️ **Note** +> +> You need both a [signer](./signers.md) and an [account](./accounts.md) for this. The commands shown in this page omit the signer and account options for better readability, and assume you've properly configured the environment variables. + +The basic format of a `starkli invoke` command is the following: + +```console +starkli invoke
+``` + +For example, to transfer `100 Wei` of the `ETH` token to the address `0x1234`, one can run: + +```console +starkli invoke 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7 transfer 0x1234 100 0 +``` + +> ℹ️ **Note** +> +> The `transfer` function takes 2 parameters (i.e. `recipient` and `amount`) but we actually need to enter 3 (note the `0` at the end). This is because `amount` is of type `u256`, which consists of 2 raw field elements. +> +> See the [simplifying invoke commands](#simplifying-invoke-commands) section below for ways to make entering this command easier. + +## Simplifying invoke commands + +You might be able to simplify invoke commands by leveraging [argument resolution](./argument-resolution.md). In this section, we will take the `ETH` transfer command above and try to simplify it. + +First, since the `0x021074834d251687180a8d007c5ffc5819e3e68993de9d2d2c32a67d9f3091ff` address is a well-known address available on the built-in address book as the `eth` entry, we can replace it with the use of the [`addr` scheme](./argument-resolution.md#addr): + +```console +starkli invoke addr:eth transfer 0x1234 100 0 +``` + +Furthermore, as the `addr:eth` is the first positional argument in an `invoke` command, it's eligible for [scheme omission](./argument-resolution.md#scheme-omission), which means we can further simplify it by dropping the `addr:` prefix: + +```console +starkli invoke eth transfer 0x1234 100 0 +``` + +Manually entering `u256` values as 2 separate field element values is tedious and error-prone, especially with larger values. We can leverage the [`u256` scheme](./argument-resolution.md#u256) to have Starkli automatically split the values for us: + +```console +starkli invoke eth transfer 0x1234 u256:100 +``` + +For more information regarding argument resolution, check out the [argument resolution](./argument-resolution.md) page. + +## Multicall support + +Starkli has seamless support for multicall. To use more than 1 contract call in an `invoke` command, simply separate the calls with `/`. + +For example, to also approve the sending of `300 Wei` for address `0x4321` in the same transaction: + +```console +starkli invoke eth transfer 0x1234 u256:100 / eth approve 0x4321 u256:300 +``` diff --git a/book/src/providers.md b/book/src/providers.md new file mode 100644 index 0000000..d8c63ff --- /dev/null +++ b/book/src/providers.md @@ -0,0 +1,75 @@ +# Providers + +Starkli connects to Starknet through "providers". Many commands require a provider to be supplied. + +Currently, two providers are supported: [JSON-RPC](#json-rpc) and the [sequencer gateway](#sequencer-gateway) (deprecated). + +> ℹ️ **Note** +> +> When no provider option is supplied, Starkli falls back to using the sequencer gateway provider for the `goerli-1` network. + +## JSON-RPC + +Starkli is centric around JSON-RPC, and the JSON-RPC provider is considered canonical. Users are strongly recommended to use JSON-RPC. There are a few options to obtain access to a JSON-RPC endpoint: + +- hosting your own node with [`pathfinder`](https://github.com/eqlabs/pathfinder); or +- using a third-party JSON-RPC API provider like [Infura](https://www.infura.io/) or [Alchemy](https://www.alchemy.com/). + +Once you have a URL to a JSON-RPC endpoint, you can use it via the `--rpc ` option for commands that expect it. For example: + +```console +starkli block-number --rpc http://localhost:9545/ +``` + +Alternatively, you can set the `STARKNET_RPC` environment variable to make command invocations easier: + +```console +export STARKNET_RPC="http://localhost:9545/" +``` + +and then, simply run: + +```console +starkli block-number +``` + +which is the same as the running with the `--rpc` option. + +## Sequencer gateway + +> ⚠️ **Warning** +> +> The sequencer gateway is deprecated and will be disabled by StarkWare soon. You're strongly recommended to use the [JSON-RPC provider](#json-rpc) instead. + +Historically, before the JSON-RPC API became available, access to the network had been possible only through a set of API offered by StarkWare known as the sequencer gateway. As of this writing, despite the wide availability of the JSON-RPC API, StarkWare still runs the sequencer gateway, but has declared it as deprecated, and encourages users to migrate to use JSON-RPC instead. + +> ℹ️ **Note** +> +> To raise awareness of the deprecation, Starkli always displays a warning message when the sequencer gateway provider is used. + +To use the sequencer gateway anyways, use the `--network ` option, where `` is one of the following: + +- `mainnet` +- `goerli-1` +- `goerli-2` +- `integration` + +For example, to check the latest block number on `mainnet`: + +```console +starkli block-number --network mainnet +``` + +Alternatively, you can set the `STARKNET_NETWORK` environment variable to make command invocations easier: + +```console +export STARKNET_NETWORK="mainnet" +``` + +and then, simply run: + +```console +starkli block-number +``` + +which is the same as the running with the `--network` option. diff --git a/book/src/ref/commands.md b/book/src/ref/commands.md new file mode 100644 index 0000000..7d0e97b --- /dev/null +++ b/book/src/ref/commands.md @@ -0,0 +1,36 @@ +# Commands + +Starkli offers the following commands: + +- selector +- class-hash +- to-cairo-string +- parse-cairo-string +- mont +- call +- transaction +- block-number +- block-hash +- block +- block-time +- state-update +- transaction-receipt +- chain-id +- nonce +- storage +- class-hash-at +- class-by-hash +- class-at +- syncing +- signer +- account +- invoke +- declare +- deploy +- completions + +To check usage of each command, run with the `--help` option. + +> 🏗️ **TODO** +> +> Document each command instead of asking users to run `--help`. diff --git a/book/src/shell-completions.md b/book/src/shell-completions.md new file mode 100644 index 0000000..f9afe57 --- /dev/null +++ b/book/src/shell-completions.md @@ -0,0 +1,30 @@ +# Shell completions + +Automatic shell completions are critical to good user experience for CLI tools. Starkli supports shell completions for the following shells: + +- _bash_ +- _elvish_ +- _fish_ +- _powershell_ +- _zsh_ + +When [installing with `starkliup`](./installation.md#using-starkliup), shell completions are automatically set up for the following shells: + +- _bash_ +- _zsh_ + +and you don't need to configure them yourself. + +Otherwise, you can generate shell completion files by running the following command: + +```console +starkli completions +``` + +which prints the content of the completion file to the standard output. For example, to generate the completion file for _fish_: + +```console +starkli completions fish +``` + +You can pipe the output into a completion file and place it at the folder expected by your shell. You might need to restart your shell session for the changes to take effect. diff --git a/book/src/signers.md b/book/src/signers.md new file mode 100644 index 0000000..ba098c1 --- /dev/null +++ b/book/src/signers.md @@ -0,0 +1,52 @@ +# Signers + +Starkli uses "signers" to sign transactions. Technically speaking, a signer can be anything that can provide valid signatures for transactions. In practice, the following signer types are currently supported: + +- [encrypted keystores](#encrypted-keystores) +- [plain text private keys](#plain-text-private-keys) + +More signer types will be supported as they become available. As of this writing, the most secure signer type is encrypted keystores. + +Signers can be created and managed through the `starkli signer` command. + +## Encrypted keystores + +Encrypted keystores are JSON files that follow the [Web3 secret storage definition](https://ethereum.org/en/developers/docs/data-structures-and-encoding/web3-secret-storage/). A password must be supplied to create a keystore, and is required for subsequently using the keystore. + +> ⚠️ **Warning** +> +> Keystores are encrypted, but they're only as secure as the password you used to create them. + +To create a fresh keystore from scratch: + +```console +starkli signer keystore new /path/to/keystore +``` + +and a keystore file will be created at `/path/to/keystore`. + +You can then use it via the `--keystore ` option for commands expecting a signer. + +Alternatively, you can set the `STARKNET_KEYSTORE` environment variable to make command invocations easier: + +```console +export STARKNET_KEYSTORE="/path/to/keystore" +``` + +> ℹ️ **Note** +> +> Even when `STARKNET_KEYSTORE` is set, it would be ignored by Starkli when any other signer option is supplied via the command line, including using the `--keystore ` option. + +## Plain text private keys + +> ⚠️ **Warning** +> +> Using plain text private keys is highly insecure. Never use this for production. + +Plain text private keys are only intended to be used for development purposes, where security of keys does not matter. To generate a private key, run the command: + +```console +starkli signer gen-keypair +``` + +For commands that expect a signer, you can then use the `--private-key ` option. diff --git a/book/src/title-page.md b/book/src/title-page.md deleted file mode 100644 index 6cff4bf..0000000 --- a/book/src/title-page.md +++ /dev/null @@ -1,3 +0,0 @@ -# starkli - -Docs for starkli.