1
1
mod client;
2
+ mod output;
2
3
3
4
use {
4
- crate :: client:: * ,
5
+ crate :: {
6
+ client:: * ,
7
+ output:: { CliStakePool , CliStakePoolDetails , CliStakePoolStakeAccountInfo , CliStakePools } ,
8
+ } ,
5
9
clap:: {
6
10
crate_description, crate_name, crate_version, value_t, value_t_or_exit, App , AppSettings ,
7
11
Arg , ArgGroup , ArgMatches , SubCommand ,
14
18
} ,
15
19
keypair:: { signer_from_path_with_config, SignerFromPathConfig } ,
16
20
} ,
21
+ solana_cli_output:: OutputFormat ,
17
22
solana_client:: rpc_client:: RpcClient ,
18
23
solana_program:: {
19
24
borsh:: { get_instance_packed_len, get_packed_len} ,
44
49
std:: { process:: exit, sync:: Arc } ,
45
50
} ;
46
51
47
- struct Config {
52
+ pub ( crate ) struct Config {
48
53
rpc_client : RpcClient ,
49
54
verbose : bool ,
55
+ output_format : OutputFormat ,
50
56
manager : Box < dyn Signer > ,
51
57
staker : Box < dyn Signer > ,
52
58
funding_authority : Option < Box < dyn Signer > > ,
@@ -852,96 +858,25 @@ fn command_deposit_sol(
852
858
853
859
fn command_list ( config : & Config , stake_pool_address : & Pubkey ) -> CommandResult {
854
860
let stake_pool = get_stake_pool ( & config. rpc_client , stake_pool_address) ?;
861
+ let reserve_stake_account_address = stake_pool. reserve_stake . to_string ( ) ;
862
+ let total_lamports = stake_pool. total_lamports ;
863
+ let last_update_epoch = stake_pool. last_update_epoch ;
855
864
let validator_list = get_validator_list ( & config. rpc_client , & stake_pool. validator_list ) ?;
865
+ let max_number_of_validators = validator_list. header . max_validators ;
866
+ let current_number_of_validators = validator_list. validators . len ( ) ;
856
867
let pool_mint = get_token_mint ( & config. rpc_client , & stake_pool. pool_mint ) ?;
857
868
let epoch_info = config. rpc_client . get_epoch_info ( ) ?;
858
869
let pool_withdraw_authority =
859
870
find_withdraw_authority_program_address ( & spl_stake_pool:: id ( ) , stake_pool_address) . 0 ;
860
- let sol_deposit_authority = stake_pool
861
- . sol_deposit_authority
862
- . map_or ( "None" . into ( ) , |pubkey| pubkey. to_string ( ) ) ;
863
- let sol_withdraw_authority = stake_pool
864
- . sol_withdraw_authority
865
- . map_or ( "None" . into ( ) , |pubkey| pubkey. to_string ( ) ) ;
866
-
867
- if config. verbose {
868
- println ! ( "Stake Pool Info" ) ;
869
- println ! ( "===============" ) ;
870
- println ! ( "Stake Pool: {}" , stake_pool_address) ;
871
- println ! ( "Validator List: {}" , stake_pool. validator_list) ;
872
- println ! ( "Manager: {}" , stake_pool. manager) ;
873
- println ! ( "Staker: {}" , stake_pool. staker) ;
874
- println ! ( "Depositor: {}" , stake_pool. stake_deposit_authority) ;
875
- println ! ( "SOL Deposit Authority: {}" , sol_deposit_authority) ;
876
- println ! ( "SOL Withdraw Authority: {}" , sol_withdraw_authority) ;
877
- println ! ( "Withdraw Authority: {}" , pool_withdraw_authority) ;
878
- println ! ( "Pool Token Mint: {}" , stake_pool. pool_mint) ;
879
- println ! ( "Fee Account: {}" , stake_pool. manager_fee_account) ;
880
- } else {
881
- println ! ( "Stake Pool: {}" , stake_pool_address) ;
882
- println ! ( "Validator List: {}" , stake_pool. validator_list) ;
883
- println ! ( "Pool Token Mint: {}" , stake_pool. pool_mint) ;
884
- }
885
-
886
- if let Some ( preferred_deposit_validator) = stake_pool. preferred_deposit_validator_vote_address {
887
- println ! (
888
- "Preferred Deposit Validator: {}" ,
889
- preferred_deposit_validator
890
- ) ;
891
- }
892
- if let Some ( preferred_withdraw_validator) = stake_pool. preferred_withdraw_validator_vote_address
893
- {
894
- println ! (
895
- "Preferred Withraw Validator: {}" ,
896
- preferred_withdraw_validator
897
- ) ;
898
- }
899
-
900
- // Display fees information
901
- println ! ( "Epoch Fee: {} of epoch rewards" , stake_pool. epoch_fee) ;
902
- println ! (
903
- "Stake Withdrawal Fee: {} of withdrawal amount" ,
904
- stake_pool. stake_withdrawal_fee
905
- ) ;
906
- println ! (
907
- "SOL Withdrawal Fee: {} of withdrawal amount" ,
908
- stake_pool. sol_withdrawal_fee
909
- ) ;
910
- println ! (
911
- "Stake Deposit Fee: {} of deposit amount" ,
912
- stake_pool. stake_deposit_fee
913
- ) ;
914
- println ! (
915
- "SOL Deposit Fee: {} of deposit amount" ,
916
- stake_pool. sol_deposit_fee
917
- ) ;
918
- println ! (
919
- "Stake Deposit Referral Fee: {}% of Stake Deposit Fee" ,
920
- stake_pool. stake_referral_fee
921
- ) ;
922
- println ! (
923
- "SOL Deposit Referral Fee: {}% of SOL Deposit Fee" ,
924
- stake_pool. sol_referral_fee
925
- ) ;
926
-
927
- if config. verbose {
928
- println ! ( ) ;
929
- println ! ( "Stake Accounts" ) ;
930
- println ! ( "--------------" ) ;
931
- }
932
871
let reserve_stake = config. rpc_client . get_account ( & stake_pool. reserve_stake ) ?;
933
872
let minimum_reserve_stake_balance = config
934
873
. rpc_client
935
874
. get_minimum_balance_for_rent_exemption ( STAKE_STATE_LEN ) ?
936
875
+ 1 ;
937
- println ! (
938
- "Reserve Account: {}\t Available Balance: {}" ,
939
- stake_pool. reserve_stake,
940
- Sol ( reserve_stake. lamports - minimum_reserve_stake_balance) ,
941
- ) ;
942
-
943
- for validator in & validator_list. validators {
944
- if config. verbose {
876
+ let cli_stake_pool_stake_account_infos = validator_list
877
+ . validators
878
+ . iter ( )
879
+ . map ( |validator| {
945
880
let ( stake_account_address, _) = find_stake_program_address (
946
881
& spl_stake_pool:: id ( ) ,
947
882
& validator. vote_account_address ,
@@ -953,55 +888,42 @@ fn command_list(config: &Config, stake_pool_address: &Pubkey) -> CommandResult {
953
888
stake_pool_address,
954
889
validator. transient_seed_suffix_start ,
955
890
) ;
956
- println ! (
957
- "Vote Account: {}\t Stake Account: {}\t Active Balance: {}\t Transient Stake Account: {}\t Transient Balance: {}\t Last Update Epoch: {}{}" ,
958
- validator. vote_account_address,
959
- stake_account_address,
960
- Sol ( validator. active_stake_lamports) ,
961
- transient_stake_account_address,
962
- Sol ( validator. transient_stake_lamports) ,
963
- validator. last_update_epoch,
964
- if validator. last_update_epoch != epoch_info. epoch {
965
- " [UPDATE REQUIRED]"
966
- } else {
967
- ""
968
- }
969
- ) ;
970
- } else {
971
- println ! (
972
- "Vote Account: {}\t Balance: {}\t Last Update Epoch: {}" ,
973
- validator. vote_account_address,
974
- Sol ( validator. stake_lamports( ) ) ,
975
- validator. last_update_epoch,
976
- ) ;
977
- }
978
- }
979
-
980
- if config. verbose {
981
- println ! ( ) ;
982
- }
983
- println ! (
984
- "Total Pool Stake: {}{}" ,
985
- Sol ( stake_pool. total_lamports) ,
986
- if stake_pool. last_update_epoch != epoch_info. epoch {
987
- " [UPDATE REQUIRED]"
988
- } else {
989
- ""
990
- }
991
- ) ;
992
- println ! (
993
- "Total Pool Tokens: {}" ,
994
- spl_token:: amount_to_ui_amount( stake_pool. pool_token_supply, pool_mint. decimals)
995
- ) ;
996
- println ! (
997
- "Current Number of Validators: {}" ,
998
- validator_list. validators. len( )
999
- ) ;
1000
- println ! (
1001
- "Max Number of Validators: {}" ,
1002
- validator_list. header. max_validators
1003
- ) ;
1004
-
891
+ let update_required = validator. last_update_epoch != epoch_info. epoch ;
892
+ CliStakePoolStakeAccountInfo {
893
+ vote_account_address : stake_pool_address. to_string ( ) ,
894
+ stake_account_address : stake_account_address. to_string ( ) ,
895
+ validator_active_stake_lamports : validator. active_stake_lamports ,
896
+ validator_last_update_epoch : validator. last_update_epoch ,
897
+ validator_lamports : validator. stake_lamports ( ) ,
898
+ validator_transient_stake_account_address : transient_stake_account_address
899
+ . to_string ( ) ,
900
+ validator_transient_stake_lamports : validator. transient_stake_lamports ,
901
+ update_required,
902
+ }
903
+ } )
904
+ . collect ( ) ;
905
+ let total_pool_tokens =
906
+ spl_token:: amount_to_ui_amount ( stake_pool. pool_token_supply , pool_mint. decimals ) ;
907
+ let mut cli_stake_pool = CliStakePool :: from ( (
908
+ * stake_pool_address,
909
+ stake_pool,
910
+ validator_list,
911
+ pool_withdraw_authority,
912
+ ) ) ;
913
+ let update_required = last_update_epoch != epoch_info. epoch ;
914
+ let cli_stake_pool_details = CliStakePoolDetails {
915
+ reserve_stake_account_address,
916
+ reserve_stake_lamports : reserve_stake. lamports ,
917
+ minimum_reserve_stake_balance,
918
+ stake_accounts : cli_stake_pool_stake_account_infos,
919
+ total_lamports,
920
+ total_pool_tokens,
921
+ current_number_of_validators : current_number_of_validators as u32 ,
922
+ max_number_of_validators,
923
+ update_required,
924
+ } ;
925
+ cli_stake_pool. details = Some ( cli_stake_pool_details) ;
926
+ println ! ( "{}" , config. output_format. formatted_string( & cli_stake_pool) ) ;
1005
927
Ok ( ( ) )
1006
928
}
1007
929
@@ -1626,18 +1548,15 @@ fn command_set_fee(
1626
1548
1627
1549
fn command_list_all_pools ( config : & Config ) -> CommandResult {
1628
1550
let all_pools = get_stake_pools ( & config. rpc_client ) ?;
1629
- let count = all_pools. len ( ) ;
1630
- for ( address, stake_pool, validator_list) in all_pools {
1631
- println ! (
1632
- "Address: {}\t Manager: {}\t Lamports: {}\t Pool tokens: {}\t Validators: {}" ,
1633
- address,
1634
- stake_pool. manager,
1635
- stake_pool. total_lamports,
1636
- stake_pool. pool_token_supply,
1637
- validator_list. validators. len( )
1638
- ) ;
1639
- }
1640
- println ! ( "Total number of pools: {}" , count) ;
1551
+ let cli_stake_pool_vec: Vec < CliStakePool > =
1552
+ all_pools. into_iter ( ) . map ( CliStakePool :: from) . collect ( ) ;
1553
+ let cli_stake_pools = CliStakePools {
1554
+ pools : cli_stake_pool_vec,
1555
+ } ;
1556
+ println ! (
1557
+ "{}" ,
1558
+ config. output_format. formatted_string( & cli_stake_pools)
1559
+ ) ;
1641
1560
Ok ( ( ) )
1642
1561
}
1643
1562
@@ -1670,6 +1589,15 @@ fn main() {
1670
1589
. global ( true )
1671
1590
. help ( "Show additional information" ) ,
1672
1591
)
1592
+ . arg (
1593
+ Arg :: with_name ( "output_format" )
1594
+ . long ( "output" )
1595
+ . value_name ( "FORMAT" )
1596
+ . global ( true )
1597
+ . takes_value ( true )
1598
+ . possible_values ( & [ "json" , "json-compact" ] )
1599
+ . help ( "Return information in specified output format" ) ,
1600
+ )
1673
1601
. arg (
1674
1602
Arg :: with_name ( "dry_run" )
1675
1603
. long ( "dry-run" )
@@ -2477,12 +2405,25 @@ fn main() {
2477
2405
} ,
2478
2406
) ;
2479
2407
let verbose = matches. is_present ( "verbose" ) ;
2408
+ let output_format = matches
2409
+ . value_of ( "output_format" )
2410
+ . map ( |value| match value {
2411
+ "json" => OutputFormat :: Json ,
2412
+ "json-compact" => OutputFormat :: JsonCompact ,
2413
+ _ => unreachable ! ( ) ,
2414
+ } )
2415
+ . unwrap_or ( if verbose {
2416
+ OutputFormat :: DisplayVerbose
2417
+ } else {
2418
+ OutputFormat :: Display
2419
+ } ) ;
2480
2420
let dry_run = matches. is_present ( "dry_run" ) ;
2481
2421
let no_update = matches. is_present ( "no_update" ) ;
2482
2422
2483
2423
Config {
2484
2424
rpc_client : RpcClient :: new_with_commitment ( json_rpc_url, CommitmentConfig :: confirmed ( ) ) ,
2485
2425
verbose,
2426
+ output_format,
2486
2427
manager,
2487
2428
staker,
2488
2429
funding_authority,
0 commit comments