Cli refactor: rename wallet to cli (#6243)

* Rename Wallet structs to Cli

* Rename wallet to cli more broadly

* Update to cli/config.yml, and update docs
This commit is contained in:
Tyera Eulberg
2019-10-04 16:13:21 -06:00
committed by GitHub
parent 2e921437cd
commit 9c9754fa0f
13 changed files with 428 additions and 446 deletions

View File

@ -188,48 +188,49 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
SUBCOMMANDS: SUBCOMMANDS:
address Get your public key address Get your public key
airdrop Request lamports airdrop Request lamports
balance Get your balance balance Get your balance
cancel Cancel a transfer cancel Cancel a transfer
claim-storage-reward Redeem storage reward credits claim-storage-reward Redeem storage reward credits
cluster-version Get the version of the cluster entrypoint cluster-version Get the version of the cluster entrypoint
confirm Confirm transaction by signature confirm Confirm transaction by signature
create-replicator-storage-account Create a replicator storage account create-replicator-storage-account Create a replicator storage account
create-stake-account Create a stake account create-stake-account Create a stake account
create-storage-mining-pool-account Create mining pool account create-validator-storage-account Create a validator storage account
create-validator-storage-account Create a validator storage account create-vote-account Create a vote account
create-vote-account Create a vote account deactivate-stake Deactivate the delegated stake from the stake account
deactivate-stake Deactivate the delegated stake from the stake account delegate-stake Delegate stake to a vote account
delegate-stake Delegate stake to a vote account deploy Deploy a program
deploy Deploy a program fees Display current cluster fees
fees Display current cluster fees get Get cli config settings
get Get wallet config settings get-epoch-info Get information about the current epoch
get-slot Get current slot get-genesis-blockhash Get the genesis blockhash
get-transaction-count Get current transaction count get-slot Get current slot
help Prints this message or the help of the given subcommand(s) get-transaction-count Get current transaction count
pay Send a payment help Prints this message or the help of the given subcommand(s)
ping Submit transactions sequentially pay Send a payment
redeem-vote-credits Redeem credits in the stake account ping Submit transactions sequentially
send-signature Send a signature to authorize a transfer redeem-vote-credits Redeem credits in the stake account
send-timestamp Send a timestamp to unlock a transfer send-signature Send a signature to authorize a transfer
set Set a wallet config setting send-timestamp Send a timestamp to unlock a transfer
show-account Show the contents of an account set Set a cli config setting
show-stake-account Show the contents of a stake account show-account Show the contents of an account
show-storage-account Show the contents of a storage account show-stake-account Show the contents of a stake account
show-vote-account Show the contents of a vote account show-storage-account Show the contents of a storage account
stake-authorize-staker Authorize a new stake signing keypair for the given stake account show-vote-account Show the contents of a vote account
stake-authorize-withdrawer Authorize a new withdraw signing keypair for the given stake account stake-authorize-staker Authorize a new stake signing keypair for the given stake account
uptime Show the uptime of a validator, based on epoch voting history stake-authorize-withdrawer Authorize a new withdraw signing keypair for the given stake account
validator-info Publish/get Validator info on Solana uptime Show the uptime of a validator, based on epoch voting history
vote-authorize-voter Authorize a new vote signing keypair for the given vote account validator-info Publish/get Validator info on Solana
vote-authorize-withdrawer Authorize a new withdraw signing keypair for the given vote account vote-authorize-voter Authorize a new vote signing keypair for the given vote account
withdraw-stake Withdraw the unstaked lamports from the stake account vote-authorize-withdrawer Authorize a new withdraw signing keypair for the given vote account
withdraw-stake Withdraw the unstaked lamports from the stake account
``` ```
#### solana-address #### solana-address
@ -245,7 +246,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
``` ```
@ -263,7 +264,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
--drone-host <HOST> Drone host to use [default: the --url host] --drone-host <HOST> Drone host to use [default: the --url host]
--drone-port <PORT> Drone port to use [default: 9900] --drone-port <PORT> Drone port to use [default: 9900]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
@ -288,7 +289,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -309,7 +310,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -330,7 +331,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -352,7 +353,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
``` ```
@ -370,7 +371,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -391,7 +392,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -413,10 +414,10 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
--authorized-staker <PUBKEY> Public key of authorized staker (defaults to wallet) --authorized-staker <PUBKEY> Public key of authorized staker (defaults to cli config pubkey)
--authorized-withdrawer <PUBKEY> Public key of the authorized withdrawer (defaults to wallet) --authorized-withdrawer <PUBKEY> Public key of the authorized withdrawer (defaults to cli config pubkey)
-C, --config <PATH> Configuration file to use [default: -C, --config <PATH> Configuration file to use [default:
~/.config/solana/wallet/config.yml] ~/.config/solana/cli/config.yml]
--custodian <PUBKEY> Identity of the custodian (can withdraw before lockup expires) --custodian <PUBKEY> Identity of the custodian (can withdraw before lockup expires)
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -428,29 +429,6 @@ ARGS:
<UNIT> Specify unit to use for request [possible values: SOL, lamports] <UNIT> Specify unit to use for request [possible values: SOL, lamports]
``` ```
#### solana-create-storage-mining-pool-account
```text
solana-create-storage-mining-pool-account
Create mining pool account
USAGE:
solana create-storage-mining-pool-account [OPTIONS] <STORAGE ACCOUNT PUBKEY> <AMOUNT> [UNIT]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json
ARGS:
<STORAGE ACCOUNT PUBKEY> Storage mining pool account address to fund
<AMOUNT> The amount to assign to the storage mining pool account (default unit SOL)
<UNIT> Specify unit to use for request [possible values: SOL, lamports]
```
#### solana-create-validator-storage-account #### solana-create-validator-storage-account
```text ```text
solana-create-validator-storage-account solana-create-validator-storage-account
@ -464,7 +442,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -479,7 +457,7 @@ solana-create-vote-account
Create a vote account Create a vote account
USAGE: USAGE:
solana create-vote-account [OPTIONS] <VOTE ACCOUNT PUBKEY> <VALIDATOR PUBKEY> <AMOUNT> [UNIT] solana create-vote-account [OPTIONS] <VOTE ACCOUNT PUBKEY> <VALIDATOR PUBKEY>
FLAGS: FLAGS:
-h, --help Prints help information -h, --help Prints help information
@ -487,18 +465,16 @@ FLAGS:
OPTIONS: OPTIONS:
--authorized-voter <PUBKEY> Public key of the authorized voter (defaults to vote account) --authorized-voter <PUBKEY> Public key of the authorized voter (defaults to vote account)
--authorized-withdrawer <PUBKEY> Public key of the authorized withdrawer (defaults to wallet) --authorized-withdrawer <PUBKEY> Public key of the authorized withdrawer (defaults to cli config pubkey)
--commission <NUM> The commission taken on reward redemption (0-255), default: 0 --commission <NUM> The commission taken on reward redemption (0-255), default: 0
-C, --config <PATH> Configuration file to use [default: -C, --config <PATH> Configuration file to use [default:
~/.config/solana/wallet/config.yml] ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
ARGS: ARGS:
<VOTE ACCOUNT PUBKEY> Vote account address to fund <VOTE ACCOUNT PUBKEY> Vote account address to fund
<VALIDATOR PUBKEY> Validator that will vote with this account <VALIDATOR PUBKEY> Validator that will vote with this account
<AMOUNT> The amount of send to the vote account (default unit SOL)
<UNIT> Specify unit to use for request [possible values: SOL, lamports]
``` ```
#### solana-deactivate-stake #### solana-deactivate-stake
@ -514,7 +490,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -536,7 +512,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -558,7 +534,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -579,7 +555,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
``` ```
@ -587,7 +563,7 @@ OPTIONS:
#### solana-get #### solana-get
```text ```text
solana-get solana-get
Get wallet config settings Get cli config settings
USAGE: USAGE:
solana get [OPTIONS] [CONFIG_FIELD] solana get [OPTIONS] [CONFIG_FIELD]
@ -597,7 +573,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -605,6 +581,42 @@ ARGS:
<CONFIG_FIELD> Return a specific config setting [possible values: url, keypair] <CONFIG_FIELD> Return a specific config setting [possible values: url, keypair]
``` ```
#### solana-get-epoch-info
```text
solana-get-epoch-info
Get information about the current epoch
USAGE:
solana get-epoch-info [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json
```
#### solana-get-genesis-blockhash
```text
solana-get-genesis-blockhash
Get the genesis blockhash
USAGE:
solana get-genesis-blockhash [OPTIONS]
FLAGS:
-h, --help Prints help information
-V, --version Prints version information
OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json
```
#### solana-get-slot #### solana-get-slot
```text ```text
solana-get-slot solana-get-slot
@ -618,7 +630,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
``` ```
@ -636,7 +648,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
``` ```
@ -668,7 +680,7 @@ FLAGS:
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: -C, --config <PATH> Configuration file to use [default:
~/.config/solana/wallet/config.yml] ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
--after <DATETIME> A timestamp after which transaction will execute --after <DATETIME> A timestamp after which transaction will execute
@ -694,7 +706,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-c, --count <NUMBER> Stop after submitting count transactions -c, --count <NUMBER> Stop after submitting count transactions
-i, --interval <SECONDS> Wait interval seconds between submitting the next transaction [default: 2] -i, --interval <SECONDS> Wait interval seconds between submitting the next transaction [default: 2]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
@ -715,7 +727,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -737,7 +749,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -759,7 +771,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
--date <DATETIME> Optional arbitrary timestamp to apply --date <DATETIME> Optional arbitrary timestamp to apply
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -772,7 +784,7 @@ ARGS:
#### solana-set #### solana-set
```text ```text
solana-set solana-set
Set a wallet config setting Set a cli config setting
USAGE: USAGE:
solana set [OPTIONS] <--url <URL>|--keypair <PATH>> solana set [OPTIONS] <--url <URL>|--keypair <PATH>>
@ -782,7 +794,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
``` ```
@ -801,7 +813,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
-o, --output <FILE> Write the account data to this file -o, --output <FILE> Write the account data to this file
@ -824,7 +836,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -845,7 +857,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -867,7 +879,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -888,7 +900,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -910,7 +922,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -933,7 +945,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
--span <NUM OF EPOCHS> Number of recent epochs to examine --span <NUM OF EPOCHS> Number of recent epochs to examine
@ -955,7 +967,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -978,7 +990,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -1000,7 +1012,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json
@ -1022,7 +1034,7 @@ FLAGS:
-V, --version Prints version information -V, --version Prints version information
OPTIONS: OPTIONS:
-C, --config <PATH> Configuration file to use [default: ~/.config/solana/wallet/config.yml] -C, --config <PATH> Configuration file to use [default: ~/.config/solana/cli/config.yml]
-u, --url <URL> JSON RPC URL for the solana cluster -u, --url <URL> JSON RPC URL for the solana cluster
-k, --keypair <PATH> /path/to/id.json -k, --keypair <PATH> /path/to/id.json

View File

@ -51,7 +51,7 @@ The Solana CLI tool points at testnet.solana.com by default. Include a `--url` a
$ solana --url http://beta.testnet.solana.com:8899 balance $ solana --url http://beta.testnet.solana.com:8899 balance
``` ```
The solana cli includes `get` and `set` configuration commands to automatically set the `--url` argument for future wallet commands. For example: The solana cli includes `get` and `set` configuration commands to automatically set the `--url` argument for future cli commands. For example:
```bash ```bash
$ solana set --url http://beta.testnet.solana.com:8899 $ solana set --url http://beta.testnet.solana.com:8899
@ -71,4 +71,3 @@ You can also submit JSON-RPC requests to a different testnet, like:
```bash ```bash
$ curl -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1, "method":"getTransactionCount"}' http://beta.testnet.solana.com:8899 $ curl -X POST -H 'Content-Type: application/json' -d '{"jsonrpc":"2.0","id":1, "method":"getTransactionCount"}' http://beta.testnet.solana.com:8899
``` ```

View File

@ -49,7 +49,7 @@ static CROSS_MARK: Emoji = Emoji("❌ ", "");
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
pub enum WalletCommand { pub enum CliCommand {
// Cluster Info Commands // Cluster Info Commands
Fees, Fees,
GetGenesisBlockhash, GetGenesisBlockhash,
@ -133,7 +133,7 @@ pub enum WalletCommand {
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum WalletError { pub enum CliError {
BadParameter(String), BadParameter(String),
CommandNotRecognized(String), CommandNotRecognized(String),
InsufficientFundsForFee, InsufficientFundsForFee,
@ -142,13 +142,13 @@ pub enum WalletError {
KeypairFileNotFound(String), KeypairFileNotFound(String),
} }
impl fmt::Display for WalletError { impl fmt::Display for CliError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "invalid") write!(f, "invalid")
} }
} }
impl error::Error for WalletError { impl error::Error for CliError {
fn description(&self) -> &str { fn description(&self) -> &str {
"invalid" "invalid"
} }
@ -159,21 +159,21 @@ impl error::Error for WalletError {
} }
} }
pub struct WalletConfig { pub struct CliConfig {
pub command: WalletCommand, pub command: CliCommand,
pub json_rpc_url: String, pub json_rpc_url: String,
pub keypair: Keypair, pub keypair: Keypair,
pub keypair_path: String, pub keypair_path: String,
pub rpc_client: Option<RpcClient>, pub rpc_client: Option<RpcClient>,
} }
impl Default for WalletConfig { impl Default for CliConfig {
fn default() -> WalletConfig { fn default() -> CliConfig {
let mut keypair_path = dirs::home_dir().expect("home directory"); let mut keypair_path = dirs::home_dir().expect("home directory");
keypair_path.extend(&[".config", "solana", "id.json"]); keypair_path.extend(&[".config", "solana", "id.json"]);
WalletConfig { CliConfig {
command: WalletCommand::Balance { command: CliCommand::Balance {
pubkey: Pubkey::default(), pubkey: Pubkey::default(),
use_lamports_unit: false, use_lamports_unit: false,
}, },
@ -188,17 +188,17 @@ impl Default for WalletConfig {
pub fn parse_command( pub fn parse_command(
pubkey: &Pubkey, pubkey: &Pubkey,
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
) -> Result<WalletCommand, Box<dyn error::Error>> { ) -> Result<CliCommand, Box<dyn error::Error>> {
let response = match matches.subcommand() { let response = match matches.subcommand() {
("address", Some(_address_matches)) => Ok(WalletCommand::Address), ("address", Some(_address_matches)) => Ok(CliCommand::Address),
("fees", Some(_fees_matches)) => Ok(WalletCommand::Fees), ("fees", Some(_fees_matches)) => Ok(CliCommand::Fees),
("airdrop", Some(airdrop_matches)) => { ("airdrop", Some(airdrop_matches)) => {
let drone_port = airdrop_matches let drone_port = airdrop_matches
.value_of("drone_port") .value_of("drone_port")
.unwrap() .unwrap()
.parse() .parse()
.or_else(|err| { .or_else(|err| {
Err(WalletError::BadParameter(format!( Err(CliError::BadParameter(format!(
"Invalid drone port: {:?}", "Invalid drone port: {:?}",
err err
))) )))
@ -206,7 +206,7 @@ pub fn parse_command(
let drone_host = if let Some(drone_host) = matches.value_of("drone_host") { let drone_host = if let Some(drone_host) = matches.value_of("drone_host") {
Some(solana_netutil::parse_host(drone_host).or_else(|err| { Some(solana_netutil::parse_host(drone_host).or_else(|err| {
Err(WalletError::BadParameter(format!( Err(CliError::BadParameter(format!(
"Invalid drone host: {:?}", "Invalid drone host: {:?}",
err err
))) )))
@ -217,7 +217,7 @@ pub fn parse_command(
let lamports = amount_of(airdrop_matches, "amount", "unit").expect("Invalid amount"); let lamports = amount_of(airdrop_matches, "amount", "unit").expect("Invalid amount");
let use_lamports_unit = airdrop_matches.value_of("unit").is_some() let use_lamports_unit = airdrop_matches.value_of("unit").is_some()
&& airdrop_matches.value_of("unit").unwrap() == "lamports"; && airdrop_matches.value_of("unit").unwrap() == "lamports";
Ok(WalletCommand::Airdrop { Ok(CliCommand::Airdrop {
drone_host, drone_host,
drone_port, drone_port,
lamports, lamports,
@ -227,21 +227,21 @@ pub fn parse_command(
("balance", Some(balance_matches)) => { ("balance", Some(balance_matches)) => {
let pubkey = pubkey_of(&balance_matches, "pubkey").unwrap_or(*pubkey); let pubkey = pubkey_of(&balance_matches, "pubkey").unwrap_or(*pubkey);
let use_lamports_unit = balance_matches.is_present("lamports"); let use_lamports_unit = balance_matches.is_present("lamports");
Ok(WalletCommand::Balance { Ok(CliCommand::Balance {
pubkey, pubkey,
use_lamports_unit, use_lamports_unit,
}) })
} }
("cancel", Some(cancel_matches)) => { ("cancel", Some(cancel_matches)) => {
let process_id = value_of(cancel_matches, "process_id").unwrap(); let process_id = value_of(cancel_matches, "process_id").unwrap();
Ok(WalletCommand::Cancel(process_id)) Ok(CliCommand::Cancel(process_id))
} }
("confirm", Some(confirm_matches)) => { ("confirm", Some(confirm_matches)) => {
match confirm_matches.value_of("signature").unwrap().parse() { match confirm_matches.value_of("signature").unwrap().parse() {
Ok(signature) => Ok(WalletCommand::Confirm(signature)), Ok(signature) => Ok(CliCommand::Confirm(signature)),
_ => { _ => {
eprintln!("{}", confirm_matches.usage()); eprintln!("{}", confirm_matches.usage());
Err(WalletError::BadParameter("Invalid signature".to_string())) Err(CliError::BadParameter("Invalid signature".to_string()))
} }
} }
} }
@ -249,7 +249,7 @@ pub fn parse_command(
let account_pubkey = pubkey_of(matches, "account_pubkey").unwrap(); let account_pubkey = pubkey_of(matches, "account_pubkey").unwrap();
let output_file = matches.value_of("output_file"); let output_file = matches.value_of("output_file");
let use_lamports_unit = matches.is_present("lamports"); let use_lamports_unit = matches.is_present("lamports");
Ok(WalletCommand::ShowAccount { Ok(CliCommand::ShowAccount {
pubkey: account_pubkey, pubkey: account_pubkey,
output_file: output_file.map(ToString::to_string), output_file: output_file.map(ToString::to_string),
use_lamports_unit, use_lamports_unit,
@ -284,16 +284,16 @@ pub fn parse_command(
} }
("claim-storage-reward", Some(matches)) => parse_storage_claim_reward(matches), ("claim-storage-reward", Some(matches)) => parse_storage_claim_reward(matches),
("show-storage-account", Some(matches)) => parse_storage_get_account_command(matches), ("show-storage-account", Some(matches)) => parse_storage_get_account_command(matches),
("deploy", Some(deploy_matches)) => Ok(WalletCommand::Deploy( ("deploy", Some(deploy_matches)) => Ok(CliCommand::Deploy(
deploy_matches deploy_matches
.value_of("program_location") .value_of("program_location")
.unwrap() .unwrap()
.to_string(), .to_string(),
)), )),
("get-genesis-blockhash", Some(_matches)) => Ok(WalletCommand::GetGenesisBlockhash), ("get-genesis-blockhash", Some(_matches)) => Ok(CliCommand::GetGenesisBlockhash),
("get-slot", Some(_matches)) => Ok(WalletCommand::GetSlot), ("get-slot", Some(_matches)) => Ok(CliCommand::GetSlot),
("get-epoch-info", Some(_matches)) => Ok(WalletCommand::GetEpochInfo), ("get-epoch-info", Some(_matches)) => Ok(CliCommand::GetEpochInfo),
("get-transaction-count", Some(_matches)) => Ok(WalletCommand::GetTransactionCount), ("get-transaction-count", Some(_matches)) => Ok(CliCommand::GetTransactionCount),
("pay", Some(pay_matches)) => { ("pay", Some(pay_matches)) => {
let lamports = amount_of(pay_matches, "amount", "unit").expect("Invalid amount"); let lamports = amount_of(pay_matches, "amount", "unit").expect("Invalid amount");
let to = value_of(&pay_matches, "to").unwrap_or(*pubkey); let to = value_of(&pay_matches, "to").unwrap_or(*pubkey);
@ -316,7 +316,7 @@ pub fn parse_command(
None None
}; };
Ok(WalletCommand::Pay { Ok(CliCommand::Pay {
lamports, lamports,
to, to,
timestamp, timestamp,
@ -333,7 +333,7 @@ pub fn parse_command(
None None
}; };
let timeout = Duration::from_secs(value_t_or_exit!(ping_matches, "timeout", u64)); let timeout = Duration::from_secs(value_t_or_exit!(ping_matches, "timeout", u64));
Ok(WalletCommand::Ping { Ok(CliCommand::Ping {
interval, interval,
count, count,
timeout, timeout,
@ -342,7 +342,7 @@ pub fn parse_command(
("send-signature", Some(sig_matches)) => { ("send-signature", Some(sig_matches)) => {
let to = value_of(&sig_matches, "to").unwrap(); let to = value_of(&sig_matches, "to").unwrap();
let process_id = value_of(&sig_matches, "process_id").unwrap(); let process_id = value_of(&sig_matches, "process_id").unwrap();
Ok(WalletCommand::Witness(to, process_id)) Ok(CliCommand::Witness(to, process_id))
} }
("send-timestamp", Some(timestamp_matches)) => { ("send-timestamp", Some(timestamp_matches)) => {
let to = value_of(&timestamp_matches, "to").unwrap(); let to = value_of(&timestamp_matches, "to").unwrap();
@ -362,15 +362,15 @@ pub fn parse_command(
} else { } else {
Utc::now() Utc::now()
}; };
Ok(WalletCommand::TimeElapsed(to, process_id, dt)) Ok(CliCommand::TimeElapsed(to, process_id, dt))
} }
("cluster-version", Some(_matches)) => Ok(WalletCommand::GetVersion), ("cluster-version", Some(_matches)) => Ok(CliCommand::GetVersion),
("validator-info", Some(matches)) => match matches.subcommand() { ("validator-info", Some(matches)) => match matches.subcommand() {
("publish", Some(matches)) => parse_validator_info_command(matches, pubkey), ("publish", Some(matches)) => parse_validator_info_command(matches, pubkey),
("get", Some(matches)) => parse_get_validator_info_command(matches), ("get", Some(matches)) => parse_get_validator_info_command(matches),
("", None) => { ("", None) => {
eprintln!("{}", matches.usage()); eprintln!("{}", matches.usage());
Err(WalletError::CommandNotRecognized( Err(CliError::CommandNotRecognized(
"no validator-info subcommand given".to_string(), "no validator-info subcommand given".to_string(),
)) ))
} }
@ -378,7 +378,7 @@ pub fn parse_command(
}, },
("", None) => { ("", None) => {
eprintln!("{}", matches.usage()); eprintln!("{}", matches.usage());
Err(WalletError::CommandNotRecognized( Err(CliError::CommandNotRecognized(
"no subcommand given".to_string(), "no subcommand given".to_string(),
)) ))
} }
@ -391,7 +391,7 @@ pub type ProcessResult = Result<String, Box<dyn error::Error>>;
pub fn check_account_for_fee( pub fn check_account_for_fee(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
fee_calculator: &FeeCalculator, fee_calculator: &FeeCalculator,
message: &Message, message: &Message,
) -> Result<(), Box<dyn error::Error>> { ) -> Result<(), Box<dyn error::Error>> {
@ -400,7 +400,7 @@ pub fn check_account_for_fee(
fn check_account_for_multiple_fees( fn check_account_for_multiple_fees(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
fee_calculator: &FeeCalculator, fee_calculator: &FeeCalculator,
messages: &[&Message], messages: &[&Message],
) -> Result<(), Box<dyn error::Error>> { ) -> Result<(), Box<dyn error::Error>> {
@ -415,15 +415,15 @@ fn check_account_for_multiple_fees(
return Ok(()); return Ok(());
} }
} }
Err(WalletError::InsufficientFundsForFee.into()) Err(CliError::InsufficientFundsForFee.into())
} }
pub fn check_unique_pubkeys( pub fn check_unique_pubkeys(
pubkey0: (&Pubkey, String), pubkey0: (&Pubkey, String),
pubkey1: (&Pubkey, String), pubkey1: (&Pubkey, String),
) -> Result<(), WalletError> { ) -> Result<(), CliError> {
if pubkey0.0 == pubkey1.0 { if pubkey0.0 == pubkey1.0 {
Err(WalletError::BadParameter(format!( Err(CliError::BadParameter(format!(
"Identical pubkeys found: `{}` and `{}` must be unique", "Identical pubkeys found: `{}` and `{}` must be unique",
pubkey0.1, pubkey1.1 pubkey0.1, pubkey1.1
))) )))
@ -442,7 +442,7 @@ fn process_fees(rpc_client: &RpcClient) -> ProcessResult {
} }
fn process_airdrop( fn process_airdrop(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
drone_addr: &SocketAddr, drone_addr: &SocketAddr,
lamports: u64, lamports: u64,
use_lamports_unit: bool, use_lamports_unit: bool,
@ -455,7 +455,7 @@ fn process_airdrop(
let previous_balance = match rpc_client.retry_get_balance(&config.keypair.pubkey(), 5)? { let previous_balance = match rpc_client.retry_get_balance(&config.keypair.pubkey(), 5)? {
Some(lamports) => lamports, Some(lamports) => lamports,
None => { None => {
return Err(WalletError::RpcRequestError( return Err(CliError::RpcRequestError(
"Received result of an unexpected type".to_string(), "Received result of an unexpected type".to_string(),
) )
.into()) .into())
@ -479,10 +479,9 @@ fn process_balance(
let balance = rpc_client.retry_get_balance(pubkey, 5)?; let balance = rpc_client.retry_get_balance(pubkey, 5)?;
match balance { match balance {
Some(lamports) => Ok(build_balance_message(lamports, use_lamports_unit)), Some(lamports) => Ok(build_balance_message(lamports, use_lamports_unit)),
None => Err(WalletError::RpcRequestError( None => Err(
"Received result of an unexpected type".to_string(), CliError::RpcRequestError("Received result of an unexpected type".to_string()).into(),
) ),
.into()),
} }
} }
@ -498,15 +497,13 @@ fn process_confirm(rpc_client: &RpcClient, signature: &Signature) -> ProcessResu
Ok("Not found".to_string()) Ok("Not found".to_string())
} }
} }
Err(err) => { Err(err) => Err(CliError::RpcRequestError(format!("Unable to confirm: {:?}", err)).into()),
Err(WalletError::RpcRequestError(format!("Unable to confirm: {:?}", err)).into())
}
} }
} }
fn process_show_account( fn process_show_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
_config: &WalletConfig, _config: &CliConfig,
account_pubkey: &Pubkey, account_pubkey: &Pubkey,
output_file: &Option<String>, output_file: &Option<String>,
use_lamports_unit: bool, use_lamports_unit: bool,
@ -537,20 +534,16 @@ fn process_show_account(
fn process_deploy( fn process_deploy(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
program_location: &str, program_location: &str,
) -> ProcessResult { ) -> ProcessResult {
let program_id = Keypair::new(); let program_id = Keypair::new();
let mut file = File::open(program_location).map_err(|err| { let mut file = File::open(program_location).map_err(|err| {
WalletError::DynamicProgramError( CliError::DynamicProgramError(format!("Unable to open program file: {}", err).to_string())
format!("Unable to open program file: {}", err).to_string(),
)
})?; })?;
let mut program_data = Vec::new(); let mut program_data = Vec::new();
file.read_to_end(&mut program_data).map_err(|err| { file.read_to_end(&mut program_data).map_err(|err| {
WalletError::DynamicProgramError( CliError::DynamicProgramError(format!("Unable to read program file: {}", err).to_string())
format!("Unable to read program file: {}", err).to_string(),
)
})?; })?;
// Build transactions to calculate fees // Build transactions to calculate fees
@ -595,9 +588,8 @@ fn process_deploy(
trace!("Creating program account"); trace!("Creating program account");
let result = let result =
rpc_client.send_and_confirm_transaction(&mut create_account_tx, &[&config.keypair]); rpc_client.send_and_confirm_transaction(&mut create_account_tx, &[&config.keypair]);
log_instruction_custom_error::<SystemError>(result).map_err(|_| { log_instruction_custom_error::<SystemError>(result)
WalletError::DynamicProgramError("Program allocate space failed".to_string()) .map_err(|_| CliError::DynamicProgramError("Program allocate space failed".to_string()))?;
})?;
trace!("Writing program data"); trace!("Writing program data");
rpc_client.send_and_confirm_transactions(write_transactions, &signers)?; rpc_client.send_and_confirm_transactions(write_transactions, &signers)?;
@ -606,7 +598,7 @@ fn process_deploy(
rpc_client rpc_client
.send_and_confirm_transaction(&mut finalize_tx, &signers) .send_and_confirm_transaction(&mut finalize_tx, &signers)
.map_err(|_| { .map_err(|_| {
WalletError::DynamicProgramError("Program finalize transaction failed".to_string()) CliError::DynamicProgramError("Program finalize transaction failed".to_string())
})?; })?;
Ok(json!({ Ok(json!({
@ -617,7 +609,7 @@ fn process_deploy(
fn process_pay( fn process_pay(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
lamports: u64, lamports: u64,
to: &Pubkey, to: &Pubkey,
timestamp: Option<DateTime<Utc>>, timestamp: Option<DateTime<Utc>>,
@ -626,7 +618,7 @@ fn process_pay(
cancelable: Option<Pubkey>, cancelable: Option<Pubkey>,
) -> ProcessResult { ) -> ProcessResult {
check_unique_pubkeys( check_unique_pubkeys(
(&config.keypair.pubkey(), "wallet keypair".to_string()), (&config.keypair.pubkey(), "cli keypair".to_string()),
(to, "to".to_string()), (to, "to".to_string()),
)?; )?;
let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?; let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
@ -671,7 +663,7 @@ fn process_pay(
let witness = if let Some(ref witness_vec) = *witnesses { let witness = if let Some(ref witness_vec) = *witnesses {
witness_vec[0] witness_vec[0]
} else { } else {
return Err(WalletError::BadParameter( return Err(CliError::BadParameter(
"Could not parse required signature pubkey(s)".to_string(), "Could not parse required signature pubkey(s)".to_string(),
) )
.into()); .into());
@ -703,7 +695,7 @@ fn process_pay(
} }
} }
fn process_cancel(rpc_client: &RpcClient, config: &WalletConfig, pubkey: &Pubkey) -> ProcessResult { fn process_cancel(rpc_client: &RpcClient, config: &CliConfig, pubkey: &Pubkey) -> ProcessResult {
let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?; let (blockhash, fee_calculator) = rpc_client.get_recent_blockhash()?;
let ix = budget_instruction::apply_signature( let ix = budget_instruction::apply_signature(
&config.keypair.pubkey(), &config.keypair.pubkey(),
@ -762,7 +754,7 @@ fn process_get_transaction_count(rpc_client: &RpcClient) -> ProcessResult {
fn process_time_elapsed( fn process_time_elapsed(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
to: &Pubkey, to: &Pubkey,
pubkey: &Pubkey, pubkey: &Pubkey,
dt: DateTime<Utc>, dt: DateTime<Utc>,
@ -778,7 +770,7 @@ fn process_time_elapsed(
fn process_witness( fn process_witness(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
to: &Pubkey, to: &Pubkey,
pubkey: &Pubkey, pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
@ -791,7 +783,7 @@ fn process_witness(
log_instruction_custom_error::<BudgetError>(result) log_instruction_custom_error::<BudgetError>(result)
} }
fn process_get_version(rpc_client: &RpcClient, config: &WalletConfig) -> ProcessResult { fn process_get_version(rpc_client: &RpcClient, config: &CliConfig) -> ProcessResult {
let remote_version: Value = serde_json::from_str(&rpc_client.get_version()?)?; let remote_version: Value = serde_json::from_str(&rpc_client.get_version()?)?;
println!( println!(
"{} {}", "{} {}",
@ -810,7 +802,7 @@ fn process_get_version(rpc_client: &RpcClient, config: &WalletConfig) -> Process
fn process_ping( fn process_ping(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
interval: &Duration, interval: &Duration,
count: &Option<u64>, count: &Option<u64>,
timeout: &Duration, timeout: &Duration,
@ -924,9 +916,9 @@ fn process_ping(
Ok("".to_string()) Ok("".to_string())
} }
pub fn process_command(config: &WalletConfig) -> ProcessResult { pub fn process_command(config: &CliConfig) -> ProcessResult {
println_name_value("Keypair:", &config.keypair_path); println_name_value("Keypair:", &config.keypair_path);
if let WalletCommand::Address = config.command { if let CliCommand::Address = config.command {
// Get address of this client // Get address of this client
return Ok(format!("{}", config.keypair.pubkey())); return Ok(format!("{}", config.keypair.pubkey()));
} }
@ -943,12 +935,12 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
match &config.command { match &config.command {
// Get address of this client // Get address of this client
WalletCommand::Address => unreachable!(), CliCommand::Address => unreachable!(),
WalletCommand::Fees => process_fees(&rpc_client), CliCommand::Fees => process_fees(&rpc_client),
// Request an airdrop from Solana Drone; // Request an airdrop from Solana Drone;
WalletCommand::Airdrop { CliCommand::Airdrop {
drone_host, drone_host,
drone_port, drone_port,
lamports, lamports,
@ -978,35 +970,33 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
} }
// Check client balance // Check client balance
WalletCommand::Balance { CliCommand::Balance {
pubkey, pubkey,
use_lamports_unit, use_lamports_unit,
} => process_balance(&pubkey, &rpc_client, *use_lamports_unit), } => process_balance(&pubkey, &rpc_client, *use_lamports_unit),
// Cancel a contract by contract Pubkey // Cancel a contract by contract Pubkey
WalletCommand::Cancel(pubkey) => process_cancel(&rpc_client, config, &pubkey), CliCommand::Cancel(pubkey) => process_cancel(&rpc_client, config, &pubkey),
// Confirm the last client transaction by signature // Confirm the last client transaction by signature
WalletCommand::Confirm(signature) => process_confirm(&rpc_client, signature), CliCommand::Confirm(signature) => process_confirm(&rpc_client, signature),
// Create vote account // Create vote account
WalletCommand::CreateVoteAccount(vote_account_pubkey, vote_init) => { CliCommand::CreateVoteAccount(vote_account_pubkey, vote_init) => {
process_create_vote_account(&rpc_client, config, &vote_account_pubkey, &vote_init) process_create_vote_account(&rpc_client, config, &vote_account_pubkey, &vote_init)
} }
WalletCommand::VoteAuthorize( CliCommand::VoteAuthorize(vote_account_pubkey, new_authorized_pubkey, vote_authorize) => {
vote_account_pubkey, process_vote_authorize(
new_authorized_pubkey, &rpc_client,
vote_authorize, config,
) => process_vote_authorize( &vote_account_pubkey,
&rpc_client, &new_authorized_pubkey,
config, *vote_authorize,
&vote_account_pubkey, )
&new_authorized_pubkey, }
*vote_authorize,
),
WalletCommand::ShowAccount { CliCommand::ShowAccount {
pubkey, pubkey,
output_file, output_file,
use_lamports_unit, use_lamports_unit,
@ -1018,7 +1008,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*use_lamports_unit, *use_lamports_unit,
), ),
WalletCommand::ShowVoteAccount { CliCommand::ShowVoteAccount {
pubkey: vote_account_pubkey, pubkey: vote_account_pubkey,
use_lamports_unit, use_lamports_unit,
} => process_show_vote_account( } => process_show_vote_account(
@ -1028,14 +1018,14 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*use_lamports_unit, *use_lamports_unit,
), ),
WalletCommand::Uptime { CliCommand::Uptime {
pubkey: vote_account_pubkey, pubkey: vote_account_pubkey,
aggregate, aggregate,
span, span,
} => process_uptime(&rpc_client, config, &vote_account_pubkey, *aggregate, *span), } => process_uptime(&rpc_client, config, &vote_account_pubkey, *aggregate, *span),
// Create stake account // Create stake account
WalletCommand::CreateStakeAccount(stake_account_pubkey, authorized, lockup, lamports) => { CliCommand::CreateStakeAccount(stake_account_pubkey, authorized, lockup, lamports) => {
process_create_stake_account( process_create_stake_account(
&rpc_client, &rpc_client,
config, config,
@ -1045,7 +1035,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*lamports, *lamports,
) )
} }
WalletCommand::DelegateStake(stake_account_pubkey, vote_account_pubkey, force) => { CliCommand::DelegateStake(stake_account_pubkey, vote_account_pubkey, force) => {
process_delegate_stake( process_delegate_stake(
&rpc_client, &rpc_client,
config, config,
@ -1054,7 +1044,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*force, *force,
) )
} }
WalletCommand::StakeAuthorize( CliCommand::StakeAuthorize(
stake_account_pubkey, stake_account_pubkey,
new_authorized_pubkey, new_authorized_pubkey,
stake_authorize, stake_authorize,
@ -1066,20 +1056,18 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*stake_authorize, *stake_authorize,
), ),
WalletCommand::WithdrawStake( CliCommand::WithdrawStake(stake_account_pubkey, destination_account_pubkey, lamports) => {
stake_account_pubkey, process_withdraw_stake(
destination_account_pubkey, &rpc_client,
lamports, config,
) => process_withdraw_stake( &stake_account_pubkey,
&rpc_client, &destination_account_pubkey,
config, *lamports,
&stake_account_pubkey, )
&destination_account_pubkey, }
*lamports,
),
// Deactivate stake account // Deactivate stake account
WalletCommand::DeactivateStake(stake_account_pubkey, vote_account_pubkey) => { CliCommand::DeactivateStake(stake_account_pubkey, vote_account_pubkey) => {
process_deactivate_stake_account( process_deactivate_stake_account(
&rpc_client, &rpc_client,
config, config,
@ -1088,7 +1076,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
) )
} }
WalletCommand::RedeemVoteCredits(stake_account_pubkey, vote_account_pubkey) => { CliCommand::RedeemVoteCredits(stake_account_pubkey, vote_account_pubkey) => {
process_redeem_vote_credits( process_redeem_vote_credits(
&rpc_client, &rpc_client,
config, config,
@ -1097,7 +1085,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
) )
} }
WalletCommand::ShowStakeAccount { CliCommand::ShowStakeAccount {
pubkey: stake_account_pubkey, pubkey: stake_account_pubkey,
use_lamports_unit, use_lamports_unit,
} => process_show_stake_account( } => process_show_stake_account(
@ -1107,7 +1095,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*use_lamports_unit, *use_lamports_unit,
), ),
WalletCommand::CreateStorageAccount { CliCommand::CreateStorageAccount {
account_owner, account_owner,
storage_account_pubkey, storage_account_pubkey,
account_type, account_type,
@ -1119,7 +1107,7 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*account_type, *account_type,
), ),
WalletCommand::ClaimStorageReward { CliCommand::ClaimStorageReward {
node_account_pubkey, node_account_pubkey,
storage_account_pubkey, storage_account_pubkey,
} => process_claim_storage_reward( } => process_claim_storage_reward(
@ -1129,22 +1117,22 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
&storage_account_pubkey, &storage_account_pubkey,
), ),
WalletCommand::ShowStorageAccount(storage_account_pubkey) => { CliCommand::ShowStorageAccount(storage_account_pubkey) => {
process_show_storage_account(&rpc_client, config, &storage_account_pubkey) process_show_storage_account(&rpc_client, config, &storage_account_pubkey)
} }
// Deploy a custom program to the chain // Deploy a custom program to the chain
WalletCommand::Deploy(ref program_location) => { CliCommand::Deploy(ref program_location) => {
process_deploy(&rpc_client, config, program_location) process_deploy(&rpc_client, config, program_location)
} }
WalletCommand::GetGenesisBlockhash => process_get_genesis_blockhash(&rpc_client), CliCommand::GetGenesisBlockhash => process_get_genesis_blockhash(&rpc_client),
WalletCommand::GetSlot => process_get_slot(&rpc_client), CliCommand::GetSlot => process_get_slot(&rpc_client),
WalletCommand::GetEpochInfo => process_get_epoch_info(&rpc_client), CliCommand::GetEpochInfo => process_get_epoch_info(&rpc_client),
WalletCommand::GetTransactionCount => process_get_transaction_count(&rpc_client), CliCommand::GetTransactionCount => process_get_transaction_count(&rpc_client),
// If client has positive balance, pay lamports to another address // If client has positive balance, pay lamports to another address
WalletCommand::Pay { CliCommand::Pay {
lamports, lamports,
to, to,
timestamp, timestamp,
@ -1162,30 +1150,30 @@ pub fn process_command(config: &WalletConfig) -> ProcessResult {
*cancelable, *cancelable,
), ),
WalletCommand::Ping { CliCommand::Ping {
interval, interval,
count, count,
timeout, timeout,
} => process_ping(&rpc_client, config, interval, count, timeout), } => process_ping(&rpc_client, config, interval, count, timeout),
// Apply time elapsed to contract // Apply time elapsed to contract
WalletCommand::TimeElapsed(to, pubkey, dt) => { CliCommand::TimeElapsed(to, pubkey, dt) => {
process_time_elapsed(&rpc_client, config, &to, &pubkey, *dt) process_time_elapsed(&rpc_client, config, &to, &pubkey, *dt)
} }
// Apply witness signature to contract // Apply witness signature to contract
WalletCommand::Witness(to, pubkey) => process_witness(&rpc_client, config, &to, &pubkey), CliCommand::Witness(to, pubkey) => process_witness(&rpc_client, config, &to, &pubkey),
// Return software version of wallet and cluster entrypoint node // Return software version of solana-cli and cluster entrypoint node
WalletCommand::GetVersion => process_get_version(&rpc_client, config), CliCommand::GetVersion => process_get_version(&rpc_client, config),
// Return all or single validator info // Return all or single validator info
WalletCommand::GetValidatorInfo(info_pubkey) => { CliCommand::GetValidatorInfo(info_pubkey) => {
process_get_validator_info(&rpc_client, *info_pubkey) process_get_validator_info(&rpc_client, *info_pubkey)
} }
// Publish validator info // Publish validator info
WalletCommand::SetValidatorInfo(validator_info, info_pubkey) => { CliCommand::SetValidatorInfo(validator_info, info_pubkey) => {
process_set_validator_info(&rpc_client, config, &validator_info, *info_pubkey) process_set_validator_info(&rpc_client, config, &validator_info, *info_pubkey)
} }
} }
@ -1682,7 +1670,7 @@ mod tests {
} }
#[test] #[test]
fn test_wallet_parse_command() { fn test_cli_parse_command() {
let test_commands = app("test", "desc", "version"); let test_commands = app("test", "desc", "version");
let pubkey = Pubkey::new_rand(); let pubkey = Pubkey::new_rand();
@ -1699,7 +1687,7 @@ mod tests {
.get_matches_from(vec!["test", "airdrop", "50", "lamports"]); .get_matches_from(vec!["test", "airdrop", "50", "lamports"]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_airdrop).unwrap(), parse_command(&pubkey, &test_airdrop).unwrap(),
WalletCommand::Airdrop { CliCommand::Airdrop {
drone_host: None, drone_host: None,
drone_port: solana_drone::drone::DRONE_PORT, drone_port: solana_drone::drone::DRONE_PORT,
lamports: 50, lamports: 50,
@ -1718,7 +1706,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_balance).unwrap(), parse_command(&pubkey, &test_balance).unwrap(),
WalletCommand::Balance { CliCommand::Balance {
pubkey: keypair.pubkey(), pubkey: keypair.pubkey(),
use_lamports_unit: false use_lamports_unit: false
} }
@ -1731,7 +1719,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_balance).unwrap(), parse_command(&pubkey, &test_balance).unwrap(),
WalletCommand::Balance { CliCommand::Balance {
pubkey: keypair.pubkey(), pubkey: keypair.pubkey(),
use_lamports_unit: true use_lamports_unit: true
} }
@ -1744,7 +1732,7 @@ mod tests {
.get_matches_from(vec!["test", "cancel", &pubkey_string]); .get_matches_from(vec!["test", "cancel", &pubkey_string]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_cancel).unwrap(), parse_command(&pubkey, &test_cancel).unwrap(),
WalletCommand::Cancel(pubkey) CliCommand::Cancel(pubkey)
); );
// Test Confirm Subcommand // Test Confirm Subcommand
@ -1756,7 +1744,7 @@ mod tests {
.get_matches_from(vec!["test", "confirm", &signature_string]); .get_matches_from(vec!["test", "confirm", &signature_string]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_confirm).unwrap(), parse_command(&pubkey, &test_confirm).unwrap(),
WalletCommand::Confirm(signature) CliCommand::Confirm(signature)
); );
let test_bad_signature = test_commands let test_bad_signature = test_commands
.clone() .clone()
@ -1770,7 +1758,7 @@ mod tests {
.get_matches_from(vec!["test", "deploy", "/Users/test/program.o"]); .get_matches_from(vec!["test", "deploy", "/Users/test/program.o"]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_deploy).unwrap(), parse_command(&pubkey, &test_deploy).unwrap(),
WalletCommand::Deploy("/Users/test/program.o".to_string()) CliCommand::Deploy("/Users/test/program.o".to_string())
); );
// Test Simple Pay Subcommand // Test Simple Pay Subcommand
@ -1783,7 +1771,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_pay).unwrap(), parse_command(&pubkey, &test_pay).unwrap(),
WalletCommand::Pay { CliCommand::Pay {
lamports: 50, lamports: 50,
to: pubkey, to: pubkey,
timestamp: None, timestamp: None,
@ -1807,7 +1795,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_pay_multiple_witnesses).unwrap(), parse_command(&pubkey, &test_pay_multiple_witnesses).unwrap(),
WalletCommand::Pay { CliCommand::Pay {
lamports: 50, lamports: 50,
to: pubkey, to: pubkey,
timestamp: None, timestamp: None,
@ -1827,7 +1815,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_pay_single_witness).unwrap(), parse_command(&pubkey, &test_pay_single_witness).unwrap(),
WalletCommand::Pay { CliCommand::Pay {
lamports: 50, lamports: 50,
to: pubkey, to: pubkey,
timestamp: None, timestamp: None,
@ -1851,7 +1839,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_pay_timestamp).unwrap(), parse_command(&pubkey, &test_pay_timestamp).unwrap(),
WalletCommand::Pay { CliCommand::Pay {
lamports: 50, lamports: 50,
to: pubkey, to: pubkey,
timestamp: Some(dt), timestamp: Some(dt),
@ -1870,7 +1858,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_send_signature).unwrap(), parse_command(&pubkey, &test_send_signature).unwrap(),
WalletCommand::Witness(pubkey, pubkey) CliCommand::Witness(pubkey, pubkey)
); );
let test_pay_multiple_witnesses = test_commands.clone().get_matches_from(vec![ let test_pay_multiple_witnesses = test_commands.clone().get_matches_from(vec![
"test", "test",
@ -1889,7 +1877,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_pay_multiple_witnesses).unwrap(), parse_command(&pubkey, &test_pay_multiple_witnesses).unwrap(),
WalletCommand::Pay { CliCommand::Pay {
lamports: 50, lamports: 50,
to: pubkey, to: pubkey,
timestamp: Some(dt), timestamp: Some(dt),
@ -1910,7 +1898,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_send_timestamp).unwrap(), parse_command(&pubkey, &test_send_timestamp).unwrap(),
WalletCommand::TimeElapsed(pubkey, pubkey, dt) CliCommand::TimeElapsed(pubkey, pubkey, dt)
); );
let test_bad_timestamp = test_commands.clone().get_matches_from(vec![ let test_bad_timestamp = test_commands.clone().get_matches_from(vec![
"test", "test",
@ -1924,40 +1912,40 @@ mod tests {
} }
#[test] #[test]
fn test_wallet_process_command() { fn test_cli_process_command() {
// Success cases // Success cases
let mut config = WalletConfig::default(); let mut config = CliConfig::default();
config.rpc_client = Some(RpcClient::new_mock("succeeds".to_string())); config.rpc_client = Some(RpcClient::new_mock("succeeds".to_string()));
let keypair = Keypair::new(); let keypair = Keypair::new();
let pubkey = keypair.pubkey().to_string(); let pubkey = keypair.pubkey().to_string();
config.keypair = keypair; config.keypair = keypair;
config.command = WalletCommand::Address; config.command = CliCommand::Address;
assert_eq!(process_command(&config).unwrap(), pubkey); assert_eq!(process_command(&config).unwrap(), pubkey);
config.command = WalletCommand::Balance { config.command = CliCommand::Balance {
pubkey: config.keypair.pubkey(), pubkey: config.keypair.pubkey(),
use_lamports_unit: true, use_lamports_unit: true,
}; };
assert_eq!(process_command(&config).unwrap(), "50 lamports"); assert_eq!(process_command(&config).unwrap(), "50 lamports");
config.command = WalletCommand::Balance { config.command = CliCommand::Balance {
pubkey: config.keypair.pubkey(), pubkey: config.keypair.pubkey(),
use_lamports_unit: false, use_lamports_unit: false,
}; };
assert_eq!(process_command(&config).unwrap(), "0 SOL"); assert_eq!(process_command(&config).unwrap(), "0 SOL");
let process_id = Pubkey::new_rand(); let process_id = Pubkey::new_rand();
config.command = WalletCommand::Cancel(process_id); config.command = CliCommand::Cancel(process_id);
assert_eq!(process_command(&config).unwrap(), SIGNATURE); assert_eq!(process_command(&config).unwrap(), SIGNATURE);
let good_signature = Signature::new(&bs58::decode(SIGNATURE).into_vec().unwrap()); let good_signature = Signature::new(&bs58::decode(SIGNATURE).into_vec().unwrap());
config.command = WalletCommand::Confirm(good_signature); config.command = CliCommand::Confirm(good_signature);
assert_eq!(process_command(&config).unwrap(), "Confirmed"); assert_eq!(process_command(&config).unwrap(), "Confirmed");
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
let node_pubkey = Pubkey::new_rand(); let node_pubkey = Pubkey::new_rand();
config.command = WalletCommand::CreateVoteAccount( config.command = CliCommand::CreateVoteAccount(
bob_pubkey, bob_pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -1971,13 +1959,13 @@ mod tests {
let new_authorized_pubkey = Pubkey::new_rand(); let new_authorized_pubkey = Pubkey::new_rand();
config.command = config.command =
WalletCommand::VoteAuthorize(bob_pubkey, new_authorized_pubkey, VoteAuthorize::Voter); CliCommand::VoteAuthorize(bob_pubkey, new_authorized_pubkey, VoteAuthorize::Voter);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
let custodian = Pubkey::new_rand(); let custodian = Pubkey::new_rand();
config.command = WalletCommand::CreateStakeAccount( config.command = CliCommand::CreateStakeAccount(
bob_pubkey, bob_pubkey,
Authorized { Authorized {
staker: config.keypair.pubkey(), staker: config.keypair.pubkey(),
@ -1991,23 +1979,23 @@ mod tests {
let stake_pubkey = Pubkey::new_rand(); let stake_pubkey = Pubkey::new_rand();
let to_pubkey = Pubkey::new_rand(); let to_pubkey = Pubkey::new_rand();
config.command = WalletCommand::WithdrawStake(stake_pubkey, to_pubkey, 100); config.command = CliCommand::WithdrawStake(stake_pubkey, to_pubkey, 100);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let stake_pubkey = Pubkey::new_rand(); let stake_pubkey = Pubkey::new_rand();
let vote_pubkey = Pubkey::new_rand(); let vote_pubkey = Pubkey::new_rand();
config.command = WalletCommand::DeactivateStake(stake_pubkey, vote_pubkey); config.command = CliCommand::DeactivateStake(stake_pubkey, vote_pubkey);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
config.command = WalletCommand::GetSlot; config.command = CliCommand::GetSlot;
assert_eq!(process_command(&config).unwrap(), "0"); assert_eq!(process_command(&config).unwrap(), "0");
config.command = WalletCommand::GetTransactionCount; config.command = CliCommand::GetTransactionCount;
assert_eq!(process_command(&config).unwrap(), "1234"); assert_eq!(process_command(&config).unwrap(), "1234");
config.command = WalletCommand::Pay { config.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: None, timestamp: None,
@ -2020,7 +2008,7 @@ mod tests {
let date_string = "\"2018-09-19T17:30:59Z\""; let date_string = "\"2018-09-19T17:30:59Z\"";
let dt: DateTime<Utc> = serde_json::from_str(&date_string).unwrap(); let dt: DateTime<Utc> = serde_json::from_str(&date_string).unwrap();
config.command = WalletCommand::Pay { config.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: Some(dt), timestamp: Some(dt),
@ -2041,7 +2029,7 @@ mod tests {
); );
let witness = Pubkey::new_rand(); let witness = Pubkey::new_rand();
config.command = WalletCommand::Pay { config.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: None, timestamp: None,
@ -2062,17 +2050,17 @@ mod tests {
); );
let process_id = Pubkey::new_rand(); let process_id = Pubkey::new_rand();
config.command = WalletCommand::TimeElapsed(bob_pubkey, process_id, dt); config.command = CliCommand::TimeElapsed(bob_pubkey, process_id, dt);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let witness = Pubkey::new_rand(); let witness = Pubkey::new_rand();
config.command = WalletCommand::Witness(bob_pubkey, witness); config.command = CliCommand::Witness(bob_pubkey, witness);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
// Need airdrop cases // Need airdrop cases
config.command = WalletCommand::Airdrop { config.command = CliCommand::Airdrop {
drone_host: None, drone_host: None,
drone_port: 1234, drone_port: 1234,
lamports: 50, lamports: 50,
@ -2081,25 +2069,25 @@ mod tests {
assert!(process_command(&config).is_ok()); assert!(process_command(&config).is_ok());
config.rpc_client = Some(RpcClient::new_mock("airdrop".to_string())); config.rpc_client = Some(RpcClient::new_mock("airdrop".to_string()));
config.command = WalletCommand::TimeElapsed(bob_pubkey, process_id, dt); config.command = CliCommand::TimeElapsed(bob_pubkey, process_id, dt);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
let witness = Pubkey::new_rand(); let witness = Pubkey::new_rand();
config.command = WalletCommand::Witness(bob_pubkey, witness); config.command = CliCommand::Witness(bob_pubkey, witness);
let signature = process_command(&config); let signature = process_command(&config);
assert_eq!(signature.unwrap(), SIGNATURE.to_string()); assert_eq!(signature.unwrap(), SIGNATURE.to_string());
// sig_not_found case // sig_not_found case
config.rpc_client = Some(RpcClient::new_mock("sig_not_found".to_string())); config.rpc_client = Some(RpcClient::new_mock("sig_not_found".to_string()));
let missing_signature = Signature::new(&bs58::decode("5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW").into_vec().unwrap()); let missing_signature = Signature::new(&bs58::decode("5VERv8NMvzbJMEkV8xnrLkEaWRtSz9CosKDYjCJjBRnbJLgp8uirBgmQpjKhoR4tjF3ZpRzrFmBV6UjKdiSZkQUW").into_vec().unwrap());
config.command = WalletCommand::Confirm(missing_signature); config.command = CliCommand::Confirm(missing_signature);
assert_eq!(process_command(&config).unwrap(), "Not found"); assert_eq!(process_command(&config).unwrap(), "Not found");
// Tx error case // Tx error case
config.rpc_client = Some(RpcClient::new_mock("account_in_use".to_string())); config.rpc_client = Some(RpcClient::new_mock("account_in_use".to_string()));
let any_signature = Signature::new(&bs58::decode(SIGNATURE).into_vec().unwrap()); let any_signature = Signature::new(&bs58::decode(SIGNATURE).into_vec().unwrap());
config.command = WalletCommand::Confirm(any_signature); config.command = CliCommand::Confirm(any_signature);
assert_eq!( assert_eq!(
process_command(&config).unwrap(), process_command(&config).unwrap(),
format!( format!(
@ -2111,7 +2099,7 @@ mod tests {
// Failure cases // Failure cases
config.rpc_client = Some(RpcClient::new_mock("fails".to_string())); config.rpc_client = Some(RpcClient::new_mock("fails".to_string()));
config.command = WalletCommand::Airdrop { config.command = CliCommand::Airdrop {
drone_host: None, drone_host: None,
drone_port: 1234, drone_port: 1234,
lamports: 50, lamports: 50,
@ -2119,13 +2107,13 @@ mod tests {
}; };
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::Balance { config.command = CliCommand::Balance {
pubkey: config.keypair.pubkey(), pubkey: config.keypair.pubkey(),
use_lamports_unit: false, use_lamports_unit: false,
}; };
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::CreateVoteAccount( config.command = CliCommand::CreateVoteAccount(
bob_pubkey, bob_pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -2136,16 +2124,16 @@ mod tests {
); );
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::VoteAuthorize(bob_pubkey, bob_pubkey, VoteAuthorize::Voter); config.command = CliCommand::VoteAuthorize(bob_pubkey, bob_pubkey, VoteAuthorize::Voter);
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::GetSlot; config.command = CliCommand::GetSlot;
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::GetTransactionCount; config.command = CliCommand::GetTransactionCount;
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::Pay { config.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: None, timestamp: None,
@ -2155,7 +2143,7 @@ mod tests {
}; };
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::Pay { config.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: Some(dt), timestamp: Some(dt),
@ -2165,7 +2153,7 @@ mod tests {
}; };
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::Pay { config.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: None, timestamp: None,
@ -2175,12 +2163,12 @@ mod tests {
}; };
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
config.command = WalletCommand::TimeElapsed(bob_pubkey, process_id, dt); config.command = CliCommand::TimeElapsed(bob_pubkey, process_id, dt);
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
} }
#[test] #[test]
fn test_wallet_deploy() { fn test_cli_deploy() {
solana_logger::setup(); solana_logger::setup();
let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
pathbuf.push("tests"); pathbuf.push("tests");
@ -2189,10 +2177,10 @@ mod tests {
pathbuf.set_extension("so"); pathbuf.set_extension("so");
// Success case // Success case
let mut config = WalletConfig::default(); let mut config = CliConfig::default();
config.rpc_client = Some(RpcClient::new_mock("deploy_succeeds".to_string())); config.rpc_client = Some(RpcClient::new_mock("deploy_succeeds".to_string()));
config.command = WalletCommand::Deploy(pathbuf.to_str().unwrap().to_string()); config.command = CliCommand::Deploy(pathbuf.to_str().unwrap().to_string());
let result = process_command(&config); let result = process_command(&config);
let json: Value = serde_json::from_str(&result.unwrap()).unwrap(); let json: Value = serde_json::from_str(&result.unwrap()).unwrap();
let program_id = json let program_id = json
@ -2206,7 +2194,7 @@ mod tests {
assert!(program_id.parse::<Pubkey>().is_ok()); assert!(program_id.parse::<Pubkey>().is_ok());
// Failure case // Failure case
config.command = WalletCommand::Deploy("bad/file/location.so".to_string()); config.command = CliCommand::Deploy("bad/file/location.so".to_string());
assert!(process_command(&config).is_err()); assert!(process_command(&config).is_err());
} }
} }

View File

@ -7,7 +7,7 @@ use std::path::Path;
lazy_static! { lazy_static! {
pub static ref CONFIG_FILE: Option<String> = { pub static ref CONFIG_FILE: Option<String> = {
dirs::home_dir().map(|mut path| { dirs::home_dir().map(|mut path| {
path.extend(&[".config", "solana", "wallet", "config.yml"]); path.extend(&[".config", "solana", "cli", "config.yml"]);
path.to_str().unwrap().to_string() path.to_str().unwrap().to_string()
}) })
}; };

View File

@ -1,6 +1,7 @@
#[macro_use] #[macro_use]
extern crate lazy_static; extern crate lazy_static;
pub mod cli;
pub mod config; pub mod config;
pub mod display; pub mod display;
pub mod input_parsers; pub mod input_parsers;
@ -9,4 +10,3 @@ pub mod stake;
pub mod storage; pub mod storage;
pub mod validator_info; pub mod validator_info;
pub mod vote; pub mod vote;
pub mod wallet;

View File

@ -1,10 +1,10 @@
use clap::{crate_description, crate_name, crate_version, Arg, ArgGroup, ArgMatches, SubCommand}; use clap::{crate_description, crate_name, crate_version, Arg, ArgGroup, ArgMatches, SubCommand};
use console::style; use console::style;
use solana_cli::{ use solana_cli::{
cli::{app, parse_command, process_command, CliConfig, CliError},
config::{self, Config}, config::{self, Config},
display::{println_name_value, println_name_value_or}, display::{println_name_value, println_name_value_or},
input_validators::is_url, input_validators::is_url,
wallet::{app, parse_command, process_command, WalletConfig, WalletError},
}; };
use solana_sdk::signature::{read_keypair, KeypairUtil}; use solana_sdk::signature::{read_keypair, KeypairUtil};
use std::error; use std::error;
@ -13,26 +13,22 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
let parse_args = match matches.subcommand() { let parse_args = match matches.subcommand() {
("get", Some(subcommand_matches)) => { ("get", Some(subcommand_matches)) => {
if let Some(config_file) = matches.value_of("config_file") { if let Some(config_file) = matches.value_of("config_file") {
let default_wallet_config = WalletConfig::default(); let default_cli_config = CliConfig::default();
let config = Config::load(config_file).unwrap_or_default(); let config = Config::load(config_file).unwrap_or_default();
if let Some(field) = subcommand_matches.value_of("specific_setting") { if let Some(field) = subcommand_matches.value_of("specific_setting") {
let (value, default_value) = match field { let (value, default_value) = match field {
"url" => (config.url, default_wallet_config.json_rpc_url), "url" => (config.url, default_cli_config.json_rpc_url),
"keypair" => (config.keypair, default_wallet_config.keypair_path), "keypair" => (config.keypair, default_cli_config.keypair_path),
_ => unreachable!(), _ => unreachable!(),
}; };
println_name_value_or(&format!("* {}:", field), &value, &default_value); println_name_value_or(&format!("* {}:", field), &value, &default_value);
} else { } else {
println_name_value("Wallet Config:", config_file); println_name_value("Wallet Config:", config_file);
println_name_value_or( println_name_value_or("* url:", &config.url, &default_cli_config.json_rpc_url);
"* url:",
&config.url,
&default_wallet_config.json_rpc_url,
);
println_name_value_or( println_name_value_or(
"* keypair:", "* keypair:",
&config.keypair, &config.keypair,
&default_wallet_config.keypair_path, &default_cli_config.keypair_path,
); );
} }
} else { } else {
@ -69,7 +65,7 @@ fn parse_settings(matches: &ArgMatches<'_>) -> Result<bool, Box<dyn error::Error
Ok(parse_args) Ok(parse_args)
} }
pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn error::Error>> { pub fn parse_args(matches: &ArgMatches<'_>) -> Result<CliConfig, Box<dyn error::Error>> {
let config = if let Some(config_file) = matches.value_of("config_file") { let config = if let Some(config_file) = matches.value_of("config_file") {
Config::load(config_file).unwrap_or_default() Config::load(config_file).unwrap_or_default()
} else { } else {
@ -80,7 +76,7 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn erro
} else if config.url != "" { } else if config.url != "" {
config.url config.url
} else { } else {
let default = WalletConfig::default(); let default = CliConfig::default();
default.json_rpc_url default.json_rpc_url
}; };
@ -89,9 +85,9 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn erro
} else if config.keypair != "" { } else if config.keypair != "" {
config.keypair config.keypair
} else { } else {
let default = WalletConfig::default(); let default = CliConfig::default();
if !std::path::Path::new(&default.keypair_path).exists() { if !std::path::Path::new(&default.keypair_path).exists() {
return Err(WalletError::KeypairFileNotFound( return Err(CliError::KeypairFileNotFound(
"Generate a new keypair with `solana-keygen new`".to_string(), "Generate a new keypair with `solana-keygen new`".to_string(),
) )
.into()); .into());
@ -99,7 +95,7 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn erro
default.keypair_path default.keypair_path
}; };
let keypair = read_keypair(&keypair_path).or_else(|err| { let keypair = read_keypair(&keypair_path).or_else(|err| {
Err(WalletError::BadParameter(format!( Err(CliError::BadParameter(format!(
"{}: Unable to open keypair file: {}", "{}: Unable to open keypair file: {}",
err, keypair_path err, keypair_path
))) )))
@ -107,7 +103,7 @@ pub fn parse_args(matches: &ArgMatches<'_>) -> Result<WalletConfig, Box<dyn erro
let command = parse_command(&keypair.pubkey(), &matches)?; let command = parse_command(&keypair.pubkey(), &matches)?;
Ok(WalletConfig { Ok(CliConfig {
command, command,
json_rpc_url, json_rpc_url,
keypair, keypair,
@ -154,7 +150,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
) )
.subcommand( .subcommand(
SubCommand::with_name("get") SubCommand::with_name("get")
.about("Get wallet config settings") .about("Get cli config settings")
.arg( .arg(
Arg::with_name("specific_setting") Arg::with_name("specific_setting")
.index(1) .index(1)
@ -166,7 +162,7 @@ fn main() -> Result<(), Box<dyn error::Error>> {
) )
.subcommand( .subcommand(
SubCommand::with_name("set") SubCommand::with_name("set")
.about("Set a wallet config setting") .about("Set a cli config setting")
.group( .group(
ArgGroup::with_name("config_settings") ArgGroup::with_name("config_settings")
.args(&["json_rpc_url", "keypair"]) .args(&["json_rpc_url", "keypair"])

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
cli::{
build_balance_message, check_account_for_fee, check_unique_pubkeys,
log_instruction_custom_error, CliCommand, CliConfig, CliError, ProcessResult,
},
input_parsers::*, input_parsers::*,
input_validators::*, input_validators::*,
wallet::{
build_balance_message, check_account_for_fee, check_unique_pubkeys,
log_instruction_custom_error, ProcessResult, WalletCommand, WalletConfig, WalletError,
},
}; };
use clap::{App, Arg, ArgMatches, SubCommand}; use clap::{App, Arg, ArgMatches, SubCommand};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
@ -73,7 +73,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY") .value_name("PUBKEY")
.takes_value(true) .takes_value(true)
.validator(is_pubkey_or_keypair) .validator(is_pubkey_or_keypair)
.help("Public key of authorized staker (defaults to wallet)") .help("Public key of authorized staker (defaults to cli config pubkey)")
) )
.arg( .arg(
Arg::with_name("authorized_withdrawer") Arg::with_name("authorized_withdrawer")
@ -81,7 +81,7 @@ impl StakeSubCommands for App<'_, '_> {
.value_name("PUBKEY") .value_name("PUBKEY")
.takes_value(true) .takes_value(true)
.validator(is_pubkey_or_keypair) .validator(is_pubkey_or_keypair)
.help("Public key of the authorized withdrawer (defaults to wallet)") .help("Public key of the authorized withdrawer (defaults to cli config pubkey)")
) )
) )
.subcommand( .subcommand(
@ -263,7 +263,7 @@ impl StakeSubCommands for App<'_, '_> {
pub fn parse_stake_create_account( pub fn parse_stake_create_account(
pubkey: &Pubkey, pubkey: &Pubkey,
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let slot = value_of(&matches, "lockup").unwrap_or(0); let slot = value_of(&matches, "lockup").unwrap_or(0);
let custodian = pubkey_of(matches, "custodian").unwrap_or_default(); let custodian = pubkey_of(matches, "custodian").unwrap_or_default();
@ -271,7 +271,7 @@ pub fn parse_stake_create_account(
let withdrawer = pubkey_of(matches, "authorized_withdrawer").unwrap_or(*pubkey); // defaults to config let withdrawer = pubkey_of(matches, "authorized_withdrawer").unwrap_or(*pubkey); // defaults to config
let lamports = amount_of(matches, "amount", "unit").expect("Invalid amount"); let lamports = amount_of(matches, "amount", "unit").expect("Invalid amount");
Ok(WalletCommand::CreateStakeAccount( Ok(CliCommand::CreateStakeAccount(
stake_account_pubkey, stake_account_pubkey,
Authorized { staker, withdrawer }, Authorized { staker, withdrawer },
Lockup { custodian, slot }, Lockup { custodian, slot },
@ -279,12 +279,12 @@ pub fn parse_stake_create_account(
)) ))
} }
pub fn parse_stake_delegate_stake(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> { pub fn parse_stake_delegate_stake(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let force = matches.is_present("force"); let force = matches.is_present("force");
Ok(WalletCommand::DelegateStake( Ok(CliCommand::DelegateStake(
stake_account_pubkey, stake_account_pubkey,
vote_account_pubkey, vote_account_pubkey,
force, force,
@ -294,53 +294,51 @@ pub fn parse_stake_delegate_stake(matches: &ArgMatches<'_>) -> Result<WalletComm
pub fn parse_stake_authorize( pub fn parse_stake_authorize(
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
stake_authorize: StakeAuthorize, stake_authorize: StakeAuthorize,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let authorized_pubkey = pubkey_of(matches, "authorized_pubkey").unwrap(); let authorized_pubkey = pubkey_of(matches, "authorized_pubkey").unwrap();
Ok(WalletCommand::StakeAuthorize( Ok(CliCommand::StakeAuthorize(
stake_account_pubkey, stake_account_pubkey,
authorized_pubkey, authorized_pubkey,
stake_authorize, stake_authorize,
)) ))
} }
pub fn parse_redeem_vote_credits(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> { pub fn parse_redeem_vote_credits(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
Ok(WalletCommand::RedeemVoteCredits( Ok(CliCommand::RedeemVoteCredits(
stake_account_pubkey, stake_account_pubkey,
vote_account_pubkey, vote_account_pubkey,
)) ))
} }
pub fn parse_stake_deactivate_stake( pub fn parse_stake_deactivate_stake(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
Ok(WalletCommand::DeactivateStake( Ok(CliCommand::DeactivateStake(
stake_account_pubkey, stake_account_pubkey,
vote_account_pubkey, vote_account_pubkey,
)) ))
} }
pub fn parse_stake_withdraw_stake(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> { pub fn parse_stake_withdraw_stake(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let destination_account_pubkey = pubkey_of(matches, "destination_account_pubkey").unwrap(); let destination_account_pubkey = pubkey_of(matches, "destination_account_pubkey").unwrap();
let lamports = amount_of(matches, "amount", "unit").expect("Invalid amount"); let lamports = amount_of(matches, "amount", "unit").expect("Invalid amount");
Ok(WalletCommand::WithdrawStake( Ok(CliCommand::WithdrawStake(
stake_account_pubkey, stake_account_pubkey,
destination_account_pubkey, destination_account_pubkey,
lamports, lamports,
)) ))
} }
pub fn parse_show_stake_account(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> { pub fn parse_show_stake_account(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap(); let stake_account_pubkey = pubkey_of(matches, "stake_account_pubkey").unwrap();
let use_lamports_unit = matches.is_present("lamports"); let use_lamports_unit = matches.is_present("lamports");
Ok(WalletCommand::ShowStakeAccount { Ok(CliCommand::ShowStakeAccount {
pubkey: stake_account_pubkey, pubkey: stake_account_pubkey,
use_lamports_unit, use_lamports_unit,
}) })
@ -348,19 +346,19 @@ pub fn parse_show_stake_account(matches: &ArgMatches<'_>) -> Result<WalletComman
pub fn process_create_stake_account( pub fn process_create_stake_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
authorized: &Authorized, authorized: &Authorized,
lockup: &Lockup, lockup: &Lockup,
lamports: u64, lamports: u64,
) -> ProcessResult { ) -> ProcessResult {
check_unique_pubkeys( check_unique_pubkeys(
(&config.keypair.pubkey(), "wallet keypair".to_string()), (&config.keypair.pubkey(), "cli keypair".to_string()),
(stake_account_pubkey, "stake_account_pubkey".to_string()), (stake_account_pubkey, "stake_account_pubkey".to_string()),
)?; )?;
if rpc_client.get_account(&stake_account_pubkey).is_ok() { if rpc_client.get_account(&stake_account_pubkey).is_ok() {
return Err(WalletError::BadParameter(format!( return Err(CliError::BadParameter(format!(
"Unable to create stake account. Stake account already exists: {}", "Unable to create stake account. Stake account already exists: {}",
stake_account_pubkey stake_account_pubkey
)) ))
@ -371,7 +369,7 @@ pub fn process_create_stake_account(
rpc_client.get_minimum_balance_for_rent_exemption(std::mem::size_of::<StakeState>())?; rpc_client.get_minimum_balance_for_rent_exemption(std::mem::size_of::<StakeState>())?;
if lamports < minimum_balance { if lamports < minimum_balance {
return Err(WalletError::BadParameter(format!( return Err(CliError::BadParameter(format!(
"need atleast {} lamports for stake account to be rent exempt, provided lamports: {}", "need atleast {} lamports for stake account to be rent exempt, provided lamports: {}",
minimum_balance, lamports minimum_balance, lamports
)) ))
@ -394,7 +392,7 @@ pub fn process_create_stake_account(
pub fn process_stake_authorize( pub fn process_stake_authorize(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
authorized_pubkey: &Pubkey, authorized_pubkey: &Pubkey,
stake_authorize: StakeAuthorize, stake_authorize: StakeAuthorize,
@ -419,7 +417,7 @@ pub fn process_stake_authorize(
pub fn process_deactivate_stake_account( pub fn process_deactivate_stake_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
@ -437,7 +435,7 @@ pub fn process_deactivate_stake_account(
pub fn process_withdraw_stake( pub fn process_withdraw_stake(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
destination_account_pubkey: &Pubkey, destination_account_pubkey: &Pubkey,
lamports: u64, lamports: u64,
@ -459,7 +457,7 @@ pub fn process_withdraw_stake(
pub fn process_redeem_vote_credits( pub fn process_redeem_vote_credits(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
@ -481,13 +479,13 @@ pub fn process_redeem_vote_credits(
pub fn process_show_stake_account( pub fn process_show_stake_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
_config: &WalletConfig, _config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
use_lamports_unit: bool, use_lamports_unit: bool,
) -> ProcessResult { ) -> ProcessResult {
let stake_account = rpc_client.get_account(stake_account_pubkey)?; let stake_account = rpc_client.get_account(stake_account_pubkey)?;
if stake_account.owner != solana_stake_api::id() { if stake_account.owner != solana_stake_api::id() {
return Err(WalletError::RpcRequestError( return Err(CliError::RpcRequestError(
format!("{:?} is not a stake account", stake_account_pubkey).to_string(), format!("{:?} is not a stake account", stake_account_pubkey).to_string(),
) )
.into()); .into());
@ -536,7 +534,7 @@ pub fn process_show_stake_account(
show_lockup(&lockup); show_lockup(&lockup);
Ok("".to_string()) Ok("".to_string())
} }
Err(err) => Err(WalletError::RpcRequestError(format!( Err(err) => Err(CliError::RpcRequestError(format!(
"Account data could not be deserialized to stake state: {:?}", "Account data could not be deserialized to stake state: {:?}",
err err
)) ))
@ -546,13 +544,13 @@ pub fn process_show_stake_account(
pub fn process_delegate_stake( pub fn process_delegate_stake(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
stake_account_pubkey: &Pubkey, stake_account_pubkey: &Pubkey,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
force: bool, force: bool,
) -> ProcessResult { ) -> ProcessResult {
check_unique_pubkeys( check_unique_pubkeys(
(&config.keypair.pubkey(), "wallet keypair".to_string()), (&config.keypair.pubkey(), "cli keypair".to_string()),
(stake_account_pubkey, "stake_account_pubkey".to_string()), (stake_account_pubkey, "stake_account_pubkey".to_string()),
)?; )?;
@ -561,23 +559,23 @@ pub fn process_delegate_stake(
let vote_account_data = rpc_client let vote_account_data = rpc_client
.get_account_data(vote_account_pubkey) .get_account_data(vote_account_pubkey)
.map_err(|_| { .map_err(|_| {
WalletError::RpcRequestError(format!("Vote account not found: {}", vote_account_pubkey)) CliError::RpcRequestError(format!("Vote account not found: {}", vote_account_pubkey))
})?; })?;
let vote_state = VoteState::deserialize(&vote_account_data).map_err(|_| { let vote_state = VoteState::deserialize(&vote_account_data).map_err(|_| {
WalletError::RpcRequestError( CliError::RpcRequestError(
"Account data could not be deserialized to vote state".to_string(), "Account data could not be deserialized to vote state".to_string(),
) )
})?; })?;
let sanity_check_result = match vote_state.root_slot { let sanity_check_result = match vote_state.root_slot {
None => Err(WalletError::BadParameter( None => Err(CliError::BadParameter(
"Unable to delegate. Vote account has no root slot".to_string(), "Unable to delegate. Vote account has no root slot".to_string(),
)), )),
Some(root_slot) => { Some(root_slot) => {
let slot = rpc_client.get_slot()?; let slot = rpc_client.get_slot()?;
if root_slot + solana_sdk::clock::DEFAULT_SLOTS_PER_TURN < slot { if root_slot + solana_sdk::clock::DEFAULT_SLOTS_PER_TURN < slot {
Err(WalletError::BadParameter( Err(CliError::BadParameter(
format!( format!(
"Unable to delegate. Vote account root slot ({}) is too old, the current slot is {}", root_slot, slot "Unable to delegate. Vote account root slot ({}) is too old, the current slot is {}", root_slot, slot
) )
@ -613,7 +611,7 @@ pub fn process_delegate_stake(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::wallet::{app, parse_command}; use crate::cli::{app, parse_command};
#[test] #[test]
fn test_parse_command() { fn test_parse_command() {
@ -629,7 +627,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_authorize_staker).unwrap(), parse_command(&pubkey, &test_authorize_staker).unwrap(),
WalletCommand::StakeAuthorize(pubkey, pubkey, StakeAuthorize::Staker) CliCommand::StakeAuthorize(pubkey, pubkey, StakeAuthorize::Staker)
); );
let test_authorize_withdrawer = test_commands.clone().get_matches_from(vec![ let test_authorize_withdrawer = test_commands.clone().get_matches_from(vec![
"test", "test",
@ -639,7 +637,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_authorize_withdrawer).unwrap(), parse_command(&pubkey, &test_authorize_withdrawer).unwrap(),
WalletCommand::StakeAuthorize(pubkey, pubkey, StakeAuthorize::Withdrawer) CliCommand::StakeAuthorize(pubkey, pubkey, StakeAuthorize::Withdrawer)
); );
// Test CreateStakeAccount SubCommand // Test CreateStakeAccount SubCommand
@ -664,7 +662,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_stake_account).unwrap(), parse_command(&pubkey, &test_create_stake_account).unwrap(),
WalletCommand::CreateStakeAccount( CliCommand::CreateStakeAccount(
pubkey, pubkey,
Authorized { Authorized {
staker: authorized, staker: authorized,
@ -686,7 +684,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_stake_account2).unwrap(), parse_command(&pubkey, &test_create_stake_account2).unwrap(),
WalletCommand::CreateStakeAccount( CliCommand::CreateStakeAccount(
pubkey, pubkey,
Authorized { Authorized {
staker: pubkey, staker: pubkey,
@ -711,7 +709,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_delegate_stake).unwrap(), parse_command(&pubkey, &test_delegate_stake).unwrap(),
WalletCommand::DelegateStake(stake_pubkey, pubkey, false,) CliCommand::DelegateStake(stake_pubkey, pubkey, false,)
); );
let test_delegate_stake = test_commands.clone().get_matches_from(vec![ let test_delegate_stake = test_commands.clone().get_matches_from(vec![
@ -723,7 +721,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_delegate_stake).unwrap(), parse_command(&pubkey, &test_delegate_stake).unwrap(),
WalletCommand::DelegateStake(stake_pubkey, pubkey, true) CliCommand::DelegateStake(stake_pubkey, pubkey, true)
); );
// Test WithdrawStake Subcommand // Test WithdrawStake Subcommand
@ -738,7 +736,7 @@ mod tests {
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_withdraw_stake).unwrap(), parse_command(&pubkey, &test_withdraw_stake).unwrap(),
WalletCommand::WithdrawStake(stake_pubkey, pubkey, 42) CliCommand::WithdrawStake(stake_pubkey, pubkey, 42)
); );
// Test DeactivateStake Subcommand // Test DeactivateStake Subcommand
@ -750,7 +748,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_deactivate_stake).unwrap(), parse_command(&pubkey, &test_deactivate_stake).unwrap(),
WalletCommand::DeactivateStake(stake_pubkey, pubkey) CliCommand::DeactivateStake(stake_pubkey, pubkey)
); );
} }
// TODO: Add process tests // TODO: Add process tests

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
cli::{
check_account_for_fee, check_unique_pubkeys, log_instruction_custom_error, CliCommand,
CliConfig, CliError, ProcessResult,
},
input_parsers::*, input_parsers::*,
input_validators::*, input_validators::*,
wallet::{
check_account_for_fee, check_unique_pubkeys, log_instruction_custom_error, ProcessResult,
WalletCommand, WalletConfig, WalletError,
},
}; };
use clap::{App, Arg, ArgMatches, SubCommand}; use clap::{App, Arg, ArgMatches, SubCommand};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
@ -100,10 +100,10 @@ impl StorageSubCommands for App<'_, '_> {
pub fn parse_storage_create_replicator_account( pub fn parse_storage_create_replicator_account(
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let account_owner = pubkey_of(matches, "storage_account_owner").unwrap(); let account_owner = pubkey_of(matches, "storage_account_owner").unwrap();
let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap(); let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap();
Ok(WalletCommand::CreateStorageAccount { Ok(CliCommand::CreateStorageAccount {
account_owner, account_owner,
storage_account_pubkey, storage_account_pubkey,
account_type: StorageAccountType::Replicator, account_type: StorageAccountType::Replicator,
@ -112,41 +112,39 @@ pub fn parse_storage_create_replicator_account(
pub fn parse_storage_create_validator_account( pub fn parse_storage_create_validator_account(
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let account_owner = pubkey_of(matches, "storage_account_owner").unwrap(); let account_owner = pubkey_of(matches, "storage_account_owner").unwrap();
let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap(); let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap();
Ok(WalletCommand::CreateStorageAccount { Ok(CliCommand::CreateStorageAccount {
account_owner, account_owner,
storage_account_pubkey, storage_account_pubkey,
account_type: StorageAccountType::Validator, account_type: StorageAccountType::Validator,
}) })
} }
pub fn parse_storage_claim_reward(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> { pub fn parse_storage_claim_reward(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
let node_account_pubkey = pubkey_of(matches, "node_account_pubkey").unwrap(); let node_account_pubkey = pubkey_of(matches, "node_account_pubkey").unwrap();
let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap(); let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap();
Ok(WalletCommand::ClaimStorageReward { Ok(CliCommand::ClaimStorageReward {
node_account_pubkey, node_account_pubkey,
storage_account_pubkey, storage_account_pubkey,
}) })
} }
pub fn parse_storage_get_account_command( pub fn parse_storage_get_account_command(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> {
let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap(); let storage_account_pubkey = pubkey_of(matches, "storage_account_pubkey").unwrap();
Ok(WalletCommand::ShowStorageAccount(storage_account_pubkey)) Ok(CliCommand::ShowStorageAccount(storage_account_pubkey))
} }
pub fn process_create_storage_account( pub fn process_create_storage_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
account_owner: &Pubkey, account_owner: &Pubkey,
storage_account_pubkey: &Pubkey, storage_account_pubkey: &Pubkey,
account_type: StorageAccountType, account_type: StorageAccountType,
) -> ProcessResult { ) -> ProcessResult {
check_unique_pubkeys( check_unique_pubkeys(
(&config.keypair.pubkey(), "wallet keypair".to_string()), (&config.keypair.pubkey(), "cli keypair".to_string()),
( (
&storage_account_pubkey, &storage_account_pubkey,
"storage_account_pubkey".to_string(), "storage_account_pubkey".to_string(),
@ -168,7 +166,7 @@ pub fn process_create_storage_account(
pub fn process_claim_storage_reward( pub fn process_claim_storage_reward(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
node_account_pubkey: &Pubkey, node_account_pubkey: &Pubkey,
storage_account_pubkey: &Pubkey, storage_account_pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
@ -187,13 +185,13 @@ pub fn process_claim_storage_reward(
pub fn process_show_storage_account( pub fn process_show_storage_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
_config: &WalletConfig, _config: &CliConfig,
storage_account_pubkey: &Pubkey, storage_account_pubkey: &Pubkey,
) -> ProcessResult { ) -> ProcessResult {
let account = rpc_client.get_account(storage_account_pubkey)?; let account = rpc_client.get_account(storage_account_pubkey)?;
if account.owner != solana_storage_api::id() { if account.owner != solana_storage_api::id() {
return Err(WalletError::RpcRequestError( return Err(CliError::RpcRequestError(
format!("{:?} is not a storage account", storage_account_pubkey).to_string(), format!("{:?} is not a storage account", storage_account_pubkey).to_string(),
) )
.into()); .into());
@ -201,7 +199,7 @@ pub fn process_show_storage_account(
use solana_storage_api::storage_contract::StorageContract; use solana_storage_api::storage_contract::StorageContract;
let storage_contract: StorageContract = account.state().map_err(|err| { let storage_contract: StorageContract = account.state().map_err(|err| {
WalletError::RpcRequestError( CliError::RpcRequestError(
format!("Unable to deserialize storage account: {:?}", err).to_string(), format!("Unable to deserialize storage account: {:?}", err).to_string(),
) )
})?; })?;
@ -213,7 +211,7 @@ pub fn process_show_storage_account(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::wallet::{app, parse_command}; use crate::cli::{app, parse_command};
#[test] #[test]
fn test_parse_command() { fn test_parse_command() {
@ -231,7 +229,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_replicator_storage_account).unwrap(), parse_command(&pubkey, &test_create_replicator_storage_account).unwrap(),
WalletCommand::CreateStorageAccount { CliCommand::CreateStorageAccount {
account_owner: pubkey, account_owner: pubkey,
storage_account_pubkey, storage_account_pubkey,
account_type: StorageAccountType::Replicator, account_type: StorageAccountType::Replicator,
@ -246,7 +244,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_validator_storage_account).unwrap(), parse_command(&pubkey, &test_create_validator_storage_account).unwrap(),
WalletCommand::CreateStorageAccount { CliCommand::CreateStorageAccount {
account_owner: pubkey, account_owner: pubkey,
storage_account_pubkey, storage_account_pubkey,
account_type: StorageAccountType::Validator, account_type: StorageAccountType::Validator,
@ -261,7 +259,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_claim_storage_reward).unwrap(), parse_command(&pubkey, &test_claim_storage_reward).unwrap(),
WalletCommand::ClaimStorageReward { CliCommand::ClaimStorageReward {
node_account_pubkey: pubkey, node_account_pubkey: pubkey,
storage_account_pubkey, storage_account_pubkey,
} }

View File

@ -1,6 +1,6 @@
use crate::{ use crate::{
cli::{check_account_for_fee, CliCommand, CliConfig, CliError, ProcessResult},
input_validators::is_url, input_validators::is_url,
wallet::{check_account_for_fee, ProcessResult, WalletCommand, WalletConfig, WalletError},
}; };
use bincode::deserialize; use bincode::deserialize;
use clap::ArgMatches; use clap::ArgMatches;
@ -142,10 +142,10 @@ fn parse_validator_info(
} }
} }
fn parse_info_pubkey(matches: &ArgMatches<'_>) -> Result<Option<Pubkey>, WalletError> { fn parse_info_pubkey(matches: &ArgMatches<'_>) -> Result<Option<Pubkey>, CliError> {
let info_pubkey = if let Some(pubkey) = matches.value_of("info_pubkey") { let info_pubkey = if let Some(pubkey) = matches.value_of("info_pubkey") {
Some(pubkey.parse::<Pubkey>().map_err(|err| { Some(pubkey.parse::<Pubkey>().map_err(|err| {
WalletError::BadParameter(format!("Invalid validator info pubkey: {:?}", err)) CliError::BadParameter(format!("Invalid validator info pubkey: {:?}", err))
})?) })?)
} else { } else {
None None
@ -156,7 +156,7 @@ fn parse_info_pubkey(matches: &ArgMatches<'_>) -> Result<Option<Pubkey>, WalletE
pub fn parse_validator_info_command( pub fn parse_validator_info_command(
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
validator_pubkey: &Pubkey, validator_pubkey: &Pubkey,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let info_pubkey = parse_info_pubkey(matches)?; let info_pubkey = parse_info_pubkey(matches)?;
// Prepare validator info // Prepare validator info
let validator_info = parse_args(&matches); let validator_info = parse_args(&matches);
@ -167,10 +167,7 @@ pub fn parse_validator_info_command(
println!("--force supplied, ignoring: {:?}", result); println!("--force supplied, ignoring: {:?}", result);
} else { } else {
result.map_err(|err| { result.map_err(|err| {
WalletError::BadParameter(format!( CliError::BadParameter(format!("Invalid validator keybase username: {:?}", err))
"Invalid validator keybase username: {:?}",
err
))
})?; })?;
} }
} }
@ -179,19 +176,17 @@ pub fn parse_validator_info_command(
let validator_info = ValidatorInfo { let validator_info = ValidatorInfo {
info: validator_string, info: validator_string,
}; };
Ok(WalletCommand::SetValidatorInfo(validator_info, info_pubkey)) Ok(CliCommand::SetValidatorInfo(validator_info, info_pubkey))
} }
pub fn parse_get_validator_info_command( pub fn parse_get_validator_info_command(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> {
let info_pubkey = parse_info_pubkey(matches)?; let info_pubkey = parse_info_pubkey(matches)?;
Ok(WalletCommand::GetValidatorInfo(info_pubkey)) Ok(CliCommand::GetValidatorInfo(info_pubkey))
} }
pub fn process_set_validator_info( pub fn process_set_validator_info(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
validator_info: &ValidatorInfo, validator_info: &ValidatorInfo,
info_pubkey: Option<Pubkey>, info_pubkey: Option<Pubkey>,
) -> ProcessResult { ) -> ProcessResult {
@ -310,7 +305,7 @@ pub fn process_get_validator_info(rpc_client: &RpcClient, pubkey: Option<Pubkey>
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::wallet::app; use crate::cli::app;
use bincode::{serialize, serialized_size}; use bincode::{serialize, serialized_size};
use serde_json::json; use serde_json::json;

View File

@ -1,10 +1,10 @@
use crate::{ use crate::{
cli::{
build_balance_message, check_account_for_fee, check_unique_pubkeys,
log_instruction_custom_error, CliCommand, CliConfig, CliError, ProcessResult,
},
input_parsers::*, input_parsers::*,
input_validators::*, input_validators::*,
wallet::{
build_balance_message, check_account_for_fee, check_unique_pubkeys,
log_instruction_custom_error, ProcessResult, WalletCommand, WalletConfig, WalletError,
},
}; };
use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand}; use clap::{value_t_or_exit, App, Arg, ArgMatches, SubCommand};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
@ -65,7 +65,7 @@ impl VoteSubCommands for App<'_, '_> {
.value_name("PUBKEY") .value_name("PUBKEY")
.takes_value(true) .takes_value(true)
.validator(is_pubkey_or_keypair) .validator(is_pubkey_or_keypair)
.help("Public key of the authorized withdrawer (defaults to wallet)"), .help("Public key of the authorized withdrawer (defaults to cli config pubkey)"),
), ),
) )
.subcommand( .subcommand(
@ -162,14 +162,14 @@ impl VoteSubCommands for App<'_, '_> {
pub fn parse_vote_create_account( pub fn parse_vote_create_account(
pubkey: &Pubkey, pubkey: &Pubkey,
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let node_pubkey = pubkey_of(matches, "node_pubkey").unwrap(); let node_pubkey = pubkey_of(matches, "node_pubkey").unwrap();
let commission = value_of(&matches, "commission").unwrap_or(0); let commission = value_of(&matches, "commission").unwrap_or(0);
let authorized_voter = pubkey_of(matches, "authorized_voter").unwrap_or(vote_account_pubkey); let authorized_voter = pubkey_of(matches, "authorized_voter").unwrap_or(vote_account_pubkey);
let authorized_withdrawer = pubkey_of(matches, "authorized_withdrawer").unwrap_or(*pubkey); let authorized_withdrawer = pubkey_of(matches, "authorized_withdrawer").unwrap_or(*pubkey);
Ok(WalletCommand::CreateVoteAccount( Ok(CliCommand::CreateVoteAccount(
vote_account_pubkey, vote_account_pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -183,29 +183,27 @@ pub fn parse_vote_create_account(
pub fn parse_vote_authorize( pub fn parse_vote_authorize(
matches: &ArgMatches<'_>, matches: &ArgMatches<'_>,
vote_authorize: VoteAuthorize, vote_authorize: VoteAuthorize,
) -> Result<WalletCommand, WalletError> { ) -> Result<CliCommand, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let new_authorized_pubkey = pubkey_of(matches, "new_authorized_pubkey").unwrap(); let new_authorized_pubkey = pubkey_of(matches, "new_authorized_pubkey").unwrap();
Ok(WalletCommand::VoteAuthorize( Ok(CliCommand::VoteAuthorize(
vote_account_pubkey, vote_account_pubkey,
new_authorized_pubkey, new_authorized_pubkey,
vote_authorize, vote_authorize,
)) ))
} }
pub fn parse_vote_get_account_command( pub fn parse_vote_get_account_command(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
matches: &ArgMatches<'_>,
) -> Result<WalletCommand, WalletError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let use_lamports_unit = matches.is_present("lamports"); let use_lamports_unit = matches.is_present("lamports");
Ok(WalletCommand::ShowVoteAccount { Ok(CliCommand::ShowVoteAccount {
pubkey: vote_account_pubkey, pubkey: vote_account_pubkey,
use_lamports_unit, use_lamports_unit,
}) })
} }
pub fn parse_vote_uptime_command(matches: &ArgMatches<'_>) -> Result<WalletCommand, WalletError> { pub fn parse_vote_uptime_command(matches: &ArgMatches<'_>) -> Result<CliCommand, CliError> {
let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap(); let vote_account_pubkey = pubkey_of(matches, "vote_account_pubkey").unwrap();
let aggregate = matches.is_present("aggregate"); let aggregate = matches.is_present("aggregate");
let span = if matches.is_present("span") { let span = if matches.is_present("span") {
@ -213,7 +211,7 @@ pub fn parse_vote_uptime_command(matches: &ArgMatches<'_>) -> Result<WalletComma
} else { } else {
None None
}; };
Ok(WalletCommand::Uptime { Ok(CliCommand::Uptime {
pubkey: vote_account_pubkey, pubkey: vote_account_pubkey,
aggregate, aggregate,
span, span,
@ -222,7 +220,7 @@ pub fn parse_vote_uptime_command(matches: &ArgMatches<'_>) -> Result<WalletComma
pub fn process_create_vote_account( pub fn process_create_vote_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
vote_init: &VoteInit, vote_init: &VoteInit,
) -> ProcessResult { ) -> ProcessResult {
@ -231,7 +229,7 @@ pub fn process_create_vote_account(
(&vote_init.node_pubkey, "node_pubkey".to_string()), (&vote_init.node_pubkey, "node_pubkey".to_string()),
)?; )?;
check_unique_pubkeys( check_unique_pubkeys(
(&config.keypair.pubkey(), "wallet keypair".to_string()), (&config.keypair.pubkey(), "cli keypair".to_string()),
(vote_account_pubkey, "vote_account_pubkey".to_string()), (vote_account_pubkey, "vote_account_pubkey".to_string()),
)?; )?;
let required_balance = let required_balance =
@ -256,7 +254,7 @@ pub fn process_create_vote_account(
pub fn process_vote_authorize( pub fn process_vote_authorize(
rpc_client: &RpcClient, rpc_client: &RpcClient,
config: &WalletConfig, config: &CliConfig,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
new_authorized_pubkey: &Pubkey, new_authorized_pubkey: &Pubkey,
vote_authorize: VoteAuthorize, vote_authorize: VoteAuthorize,
@ -281,21 +279,21 @@ pub fn process_vote_authorize(
pub fn process_show_vote_account( pub fn process_show_vote_account(
rpc_client: &RpcClient, rpc_client: &RpcClient,
_config: &WalletConfig, _config: &CliConfig,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
use_lamports_unit: bool, use_lamports_unit: bool,
) -> ProcessResult { ) -> ProcessResult {
let vote_account = rpc_client.get_account(vote_account_pubkey)?; let vote_account = rpc_client.get_account(vote_account_pubkey)?;
if vote_account.owner != solana_vote_api::id() { if vote_account.owner != solana_vote_api::id() {
return Err(WalletError::RpcRequestError( return Err(CliError::RpcRequestError(
format!("{:?} is not a vote account", vote_account_pubkey).to_string(), format!("{:?} is not a vote account", vote_account_pubkey).to_string(),
) )
.into()); .into());
} }
let vote_state = VoteState::deserialize(&vote_account.data).map_err(|_| { let vote_state = VoteState::deserialize(&vote_account.data).map_err(|_| {
WalletError::RpcRequestError( CliError::RpcRequestError(
"Account data could not be deserialized to vote state".to_string(), "Account data could not be deserialized to vote state".to_string(),
) )
})?; })?;
@ -354,7 +352,7 @@ pub fn process_show_vote_account(
pub fn process_uptime( pub fn process_uptime(
rpc_client: &RpcClient, rpc_client: &RpcClient,
_config: &WalletConfig, _config: &CliConfig,
vote_account_pubkey: &Pubkey, vote_account_pubkey: &Pubkey,
aggregate: bool, aggregate: bool,
span: Option<u64>, span: Option<u64>,
@ -362,14 +360,14 @@ pub fn process_uptime(
let vote_account = rpc_client.get_account(vote_account_pubkey)?; let vote_account = rpc_client.get_account(vote_account_pubkey)?;
if vote_account.owner != solana_vote_api::id() { if vote_account.owner != solana_vote_api::id() {
return Err(WalletError::RpcRequestError( return Err(CliError::RpcRequestError(
format!("{:?} is not a vote account", vote_account_pubkey).to_string(), format!("{:?} is not a vote account", vote_account_pubkey).to_string(),
) )
.into()); .into());
} }
let vote_state = VoteState::deserialize(&vote_account.data).map_err(|_| { let vote_state = VoteState::deserialize(&vote_account.data).map_err(|_| {
WalletError::RpcRequestError( CliError::RpcRequestError(
"Account data could not be deserialized to vote state".to_string(), "Account data could not be deserialized to vote state".to_string(),
) )
})?; })?;
@ -424,7 +422,7 @@ pub fn process_uptime(
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::wallet::{app, parse_command}; use crate::cli::{app, parse_command};
#[test] #[test]
fn test_parse_command() { fn test_parse_command() {
@ -440,7 +438,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_authorize_voter).unwrap(), parse_command(&pubkey, &test_authorize_voter).unwrap(),
WalletCommand::VoteAuthorize(pubkey, pubkey, VoteAuthorize::Voter) CliCommand::VoteAuthorize(pubkey, pubkey, VoteAuthorize::Voter)
); );
// Test CreateVoteAccount SubCommand // Test CreateVoteAccount SubCommand
@ -456,7 +454,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_vote_account).unwrap(), parse_command(&pubkey, &test_create_vote_account).unwrap(),
WalletCommand::CreateVoteAccount( CliCommand::CreateVoteAccount(
pubkey, pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -474,7 +472,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_vote_account2).unwrap(), parse_command(&pubkey, &test_create_vote_account2).unwrap(),
WalletCommand::CreateVoteAccount( CliCommand::CreateVoteAccount(
pubkey, pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -496,7 +494,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_vote_account3).unwrap(), parse_command(&pubkey, &test_create_vote_account3).unwrap(),
WalletCommand::CreateVoteAccount( CliCommand::CreateVoteAccount(
pubkey, pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -517,7 +515,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &test_create_vote_account4).unwrap(), parse_command(&pubkey, &test_create_vote_account4).unwrap(),
WalletCommand::CreateVoteAccount( CliCommand::CreateVoteAccount(
pubkey, pubkey,
VoteInit { VoteInit {
node_pubkey, node_pubkey,
@ -540,7 +538,7 @@ mod tests {
]); ]);
assert_eq!( assert_eq!(
parse_command(&pubkey, &matches).unwrap(), parse_command(&pubkey, &matches).unwrap(),
WalletCommand::Uptime { CliCommand::Uptime {
pubkey, pubkey,
aggregate: true, aggregate: true,
span: Some(4) span: Some(4)

View File

@ -1,5 +1,5 @@
use serde_json::{json, Value}; use serde_json::{json, Value};
use solana_cli::wallet::{process_command, WalletCommand, WalletConfig}; use solana_cli::cli::{process_command, CliCommand, CliConfig};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
use solana_client::rpc_request::RpcRequest; use solana_client::rpc_request::RpcRequest;
use solana_core::validator::new_validator_for_tests; use solana_core::validator::new_validator_for_tests;
@ -11,7 +11,7 @@ use std::path::PathBuf;
use std::sync::mpsc::channel; use std::sync::mpsc::channel;
#[test] #[test]
fn test_wallet_deploy_program() { fn test_cli_deploy_program() {
solana_logger::setup(); solana_logger::setup();
let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR")); let mut pathbuf = PathBuf::from(env!("CARGO_MANIFEST_DIR"));
@ -35,9 +35,9 @@ fn test_wallet_deploy_program() {
.get_minimum_balance_for_rent_exemption(program_data.len()) .get_minimum_balance_for_rent_exemption(program_data.len())
.unwrap(); .unwrap();
let mut config = WalletConfig::default(); let mut config = CliConfig::default();
config.json_rpc_url = format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port()); config.json_rpc_url = format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port());
config.command = WalletCommand::Airdrop { config.command = CliCommand::Airdrop {
drone_host: None, drone_host: None,
drone_port: drone_addr.port(), drone_port: drone_addr.port(),
lamports: minimum_balance_for_rent_exemption + 1, // min balance for rent exemption + leftover for tx processing lamports: minimum_balance_for_rent_exemption + 1, // min balance for rent exemption + leftover for tx processing
@ -45,7 +45,7 @@ fn test_wallet_deploy_program() {
}; };
process_command(&config).unwrap(); process_command(&config).unwrap();
config.command = WalletCommand::Deploy(pathbuf.to_str().unwrap().to_string()); config.command = CliCommand::Deploy(pathbuf.to_str().unwrap().to_string());
let response = process_command(&config); let response = process_command(&config);
let json: Value = serde_json::from_str(&response.unwrap()).unwrap(); let json: Value = serde_json::from_str(&response.unwrap()).unwrap();

View File

@ -1,8 +1,6 @@
use chrono::prelude::*; use chrono::prelude::*;
use serde_json::Value; use serde_json::Value;
use solana_cli::wallet::{ use solana_cli::cli::{process_command, request_and_confirm_airdrop, CliCommand, CliConfig};
process_command, request_and_confirm_airdrop, WalletCommand, WalletConfig,
};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
use solana_drone::drone::run_local_drone; use solana_drone::drone::run_local_drone;
use solana_sdk::pubkey::Pubkey; use solana_sdk::pubkey::Pubkey;
@ -29,7 +27,7 @@ fn check_balance(expected_balance: u64, client: &RpcClient, pubkey: &Pubkey) {
} }
#[test] #[test]
fn test_wallet_timestamp_tx() { fn test_cli_timestamp_tx() {
let (server, leader_data, alice, ledger_path) = new_validator_for_tests(); let (server, leader_data, alice, ledger_path) = new_validator_for_tests();
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
@ -39,11 +37,11 @@ fn test_wallet_timestamp_tx() {
let rpc_client = RpcClient::new_socket(leader_data.rpc); let rpc_client = RpcClient::new_socket(leader_data.rpc);
let mut config_payer = WalletConfig::default(); let mut config_payer = CliConfig::default();
config_payer.json_rpc_url = config_payer.json_rpc_url =
format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port()); format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port());
let mut config_witness = WalletConfig::default(); let mut config_witness = CliConfig::default();
config_witness.json_rpc_url = config_payer.json_rpc_url.clone(); config_witness.json_rpc_url = config_payer.json_rpc_url.clone();
assert_ne!( assert_ne!(
@ -66,7 +64,7 @@ fn test_wallet_timestamp_tx() {
// Make transaction (from config_payer to bob_pubkey) requiring timestamp from config_witness // Make transaction (from config_payer to bob_pubkey) requiring timestamp from config_witness
let date_string = "\"2018-09-19T17:30:59Z\""; let date_string = "\"2018-09-19T17:30:59Z\"";
let dt: DateTime<Utc> = serde_json::from_str(&date_string).unwrap(); let dt: DateTime<Utc> = serde_json::from_str(&date_string).unwrap();
config_payer.command = WalletCommand::Pay { config_payer.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: Some(dt), timestamp: Some(dt),
@ -88,7 +86,7 @@ fn test_wallet_timestamp_tx() {
check_balance(0, &rpc_client, &bob_pubkey); // recipient balance check_balance(0, &rpc_client, &bob_pubkey); // recipient balance
// Sign transaction by config_witness // Sign transaction by config_witness
config_witness.command = WalletCommand::TimeElapsed(bob_pubkey, process_id, dt); config_witness.command = CliCommand::TimeElapsed(bob_pubkey, process_id, dt);
process_command(&config_witness).unwrap(); process_command(&config_witness).unwrap();
check_balance(40, &rpc_client, &config_payer.keypair.pubkey()); // config_payer balance check_balance(40, &rpc_client, &config_payer.keypair.pubkey()); // config_payer balance
@ -100,7 +98,7 @@ fn test_wallet_timestamp_tx() {
} }
#[test] #[test]
fn test_wallet_witness_tx() { fn test_cli_witness_tx() {
let (server, leader_data, alice, ledger_path) = new_validator_for_tests(); let (server, leader_data, alice, ledger_path) = new_validator_for_tests();
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
@ -110,11 +108,11 @@ fn test_wallet_witness_tx() {
let rpc_client = RpcClient::new_socket(leader_data.rpc); let rpc_client = RpcClient::new_socket(leader_data.rpc);
let mut config_payer = WalletConfig::default(); let mut config_payer = CliConfig::default();
config_payer.json_rpc_url = config_payer.json_rpc_url =
format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port()); format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port());
let mut config_witness = WalletConfig::default(); let mut config_witness = CliConfig::default();
config_witness.json_rpc_url = config_payer.json_rpc_url.clone(); config_witness.json_rpc_url = config_payer.json_rpc_url.clone();
assert_ne!( assert_ne!(
@ -133,7 +131,7 @@ fn test_wallet_witness_tx() {
.unwrap(); .unwrap();
// Make transaction (from config_payer to bob_pubkey) requiring witness signature from config_witness // Make transaction (from config_payer to bob_pubkey) requiring witness signature from config_witness
config_payer.command = WalletCommand::Pay { config_payer.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: None, timestamp: None,
@ -155,7 +153,7 @@ fn test_wallet_witness_tx() {
check_balance(0, &rpc_client, &bob_pubkey); // recipient balance check_balance(0, &rpc_client, &bob_pubkey); // recipient balance
// Sign transaction by config_witness // Sign transaction by config_witness
config_witness.command = WalletCommand::Witness(bob_pubkey, process_id); config_witness.command = CliCommand::Witness(bob_pubkey, process_id);
process_command(&config_witness).unwrap(); process_command(&config_witness).unwrap();
check_balance(40, &rpc_client, &config_payer.keypair.pubkey()); // config_payer balance check_balance(40, &rpc_client, &config_payer.keypair.pubkey()); // config_payer balance
@ -167,7 +165,7 @@ fn test_wallet_witness_tx() {
} }
#[test] #[test]
fn test_wallet_cancel_tx() { fn test_cli_cancel_tx() {
let (server, leader_data, alice, ledger_path) = new_validator_for_tests(); let (server, leader_data, alice, ledger_path) = new_validator_for_tests();
let bob_pubkey = Pubkey::new_rand(); let bob_pubkey = Pubkey::new_rand();
@ -177,11 +175,11 @@ fn test_wallet_cancel_tx() {
let rpc_client = RpcClient::new_socket(leader_data.rpc); let rpc_client = RpcClient::new_socket(leader_data.rpc);
let mut config_payer = WalletConfig::default(); let mut config_payer = CliConfig::default();
config_payer.json_rpc_url = config_payer.json_rpc_url =
format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port()); format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port());
let mut config_witness = WalletConfig::default(); let mut config_witness = CliConfig::default();
config_witness.json_rpc_url = config_payer.json_rpc_url.clone(); config_witness.json_rpc_url = config_payer.json_rpc_url.clone();
assert_ne!( assert_ne!(
@ -193,7 +191,7 @@ fn test_wallet_cancel_tx() {
.unwrap(); .unwrap();
// Make transaction (from config_payer to bob_pubkey) requiring witness signature from config_witness // Make transaction (from config_payer to bob_pubkey) requiring witness signature from config_witness
config_payer.command = WalletCommand::Pay { config_payer.command = CliCommand::Pay {
lamports: 10, lamports: 10,
to: bob_pubkey, to: bob_pubkey,
timestamp: None, timestamp: None,
@ -215,7 +213,7 @@ fn test_wallet_cancel_tx() {
check_balance(0, &rpc_client, &bob_pubkey); // recipient balance check_balance(0, &rpc_client, &bob_pubkey); // recipient balance
// Sign transaction by config_witness // Sign transaction by config_witness
config_payer.command = WalletCommand::Cancel(process_id); config_payer.command = CliCommand::Cancel(process_id);
process_command(&config_payer).unwrap(); process_command(&config_payer).unwrap();
check_balance(50, &rpc_client, &config_payer.keypair.pubkey()); // config_payer balance check_balance(50, &rpc_client, &config_payer.keypair.pubkey()); // config_payer balance

View File

@ -1,4 +1,4 @@
use solana_cli::wallet::{process_command, WalletCommand, WalletConfig}; use solana_cli::cli::{process_command, CliCommand, CliConfig};
use solana_client::rpc_client::RpcClient; use solana_client::rpc_client::RpcClient;
use solana_core::validator::new_validator_for_tests; use solana_core::validator::new_validator_for_tests;
use solana_drone::drone::run_local_drone; use solana_drone::drone::run_local_drone;
@ -7,15 +7,15 @@ use std::fs::remove_dir_all;
use std::sync::mpsc::channel; use std::sync::mpsc::channel;
#[test] #[test]
fn test_wallet_request_airdrop() { fn test_cli_request_airdrop() {
let (server, leader_data, alice, ledger_path) = new_validator_for_tests(); let (server, leader_data, alice, ledger_path) = new_validator_for_tests();
let (sender, receiver) = channel(); let (sender, receiver) = channel();
run_local_drone(alice, sender, None); run_local_drone(alice, sender, None);
let drone_addr = receiver.recv().unwrap(); let drone_addr = receiver.recv().unwrap();
let mut bob_config = WalletConfig::default(); let mut bob_config = CliConfig::default();
bob_config.json_rpc_url = format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port()); bob_config.json_rpc_url = format!("http://{}:{}", leader_data.rpc.ip(), leader_data.rpc.port());
bob_config.command = WalletCommand::Airdrop { bob_config.command = CliCommand::Airdrop {
drone_host: None, drone_host: None,
drone_port: drone_addr.port(), drone_port: drone_addr.port(),
lamports: 50, lamports: 50,