Skip to content

Commit

Permalink
docs: document vm.prompt (#1151)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tudmotu authored Mar 23, 2024
1 parent e6ab931 commit 214dba7
Show file tree
Hide file tree
Showing 4 changed files with 119 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@
- [`transact`](./cheatcodes/transact.md)
- [External](./cheatcodes/external.md)
- [`ffi`](./cheatcodes/ffi.md)
- [`prompt`](./cheatcodes/prompt.md)
- [`projectRoot`](./cheatcodes/project-root.md)
- [`getCode`](./cheatcodes/get-code.md)
- [`getDeployedCode`](./cheatcodes/get-deployed-code.md)
Expand Down
1 change: 1 addition & 0 deletions src/cheatcodes/external.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## External

- [`ffi`](./ffi.md)
- [`prompt`](./prompt.md)
- [`projectRoot`](./project-root.md)
- [`getCode`](./get-code.md)
- [`getDeployedCode`](./get-deployed-code.md)
Expand Down
109 changes: 109 additions & 0 deletions src/cheatcodes/prompt.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
## `prompt`

### Signature

```solidity
function prompt(string calldata promptText) external returns (string memory input);
function promptSecret(string calldata promptText) external returns (string memory input);
```

### Description

Display an interactive prompt to the user for inserting arbitrary data.

`vm.prompt` displays an interactive input, while `vm.promptSecret` displays a
hidden input, used for passwords and other secret information that should not
leak to the terminal.

> ℹ️ **Note**
>
> This cheatcode is meant to be used in scripts ― not tests. It is also advised to
> follow the best practices below for testing scripts that use `vm.prompt` and
> handling timeouts, since scripts might otherwise hang or revert. This cheatcode
> reverts when running in a non-interactive shell.
### Configuration

In order to prevent unwanted hangups, `vm.prompt` has a timeout configuration.

In your `foundry.toml`:

```toml
prompt_timeout = 120
```

Default value is `120` and values are in seconds.

### Best practices

#### Testing scripts that use `vm.prompt`

When testing scripts containing `vm.prompt` it is recommended to use the
following pattern:

```solidity
contract Script {
function run() public {
uint256 myUint = vm.parseUint(vm.prompt("enter uint"));
run(myUint);
}
function run(uint256 myUint) public {
// actual logic
}
}
```

That way, we are keeping the UX gain (don't have to provide `--sig` argument
when running the script), but tests can set any value to `myUint` and not just
a hardcoded default.

#### Handling timeouts

When a user fails to provide an input before the timeout expires, the
`vm.prompt` cheatcode reverts. If you'd like, timeouts can be handled by using
`try/catch`:

```solidity
string memory input;
try vm.prompt("Username") returns (string memory res) {
input = res;
}
catch (bytes memory) {
input = "Anonymous";
}
```

### Examples

#### Choose RPC endpoint

Provide an option to choose the RPC/chain to run on.

In your `foundry.toml` file:

```toml
[rpc_endpoints]
mainnet = "https://eth.llamarpc.com"
polygon = "https://polygon.llamarpc.com"
```

In your script:

```solidity
string memory rpcEndpoint = vm.prompt("RPC endpoint");
vm.createSelectFork(rpcEndpoint);
```

#### Parse user input into native types

We can use the string parsing cheatcodes to parse the responses from users:

```solidity
uint privateKey = uint(vm.parseBytes32(vm.promptSecret("Private key")));
address to = vm.parseAddress(vm.prompt("Send to"));
uint amount = vm.parseUint(vm.prompt("Amount (wei)"));
vm.broadcast(privateKey);
payable(to).transfer(amount);
```
8 changes: 8 additions & 0 deletions src/reference/config/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,14 @@ optimism = "https://optimism.alchemyapi.io/v2/..."
mainnet = "${RPC_MAINNET}"
```

##### `prompt_timeout`

- Type: integer
- Default: 120
- Environment: `FOUNDRY_PROMPT_TIMEOUT`

The number of seconds to wait before `vm.prompt` reverts with a timeout.

### Fuzz

Configuration values for `[fuzz]` section.
Expand Down

0 comments on commit 214dba7

Please sign in to comment.