casper_client/
cli.rs

1//! An API suitable for use by a CLI binary.
2//!
3//! It provides functions and types largely based around strings and integers, as would be expected
4//! to be input by a CLI user.  The functions then parse these inputs into the expected Rust types
5//! and pass them through to the equivalent API functions defined in the root of the library.
6//!
7//! # Common Parameters
8//!
9//! Many of the functions have similar parameters.  Descriptions for these common ones follow:
10//!
11//! * `maybe_rpc_id` - The JSON-RPC identifier, applied to the request and returned in the response.
12//!   If it can be parsed as an `i64` it will be used as a JSON integer. If empty, a random `i64`
13//!   will be assigned.  Otherwise the provided string will be used verbatim.
14//! * `node_address` - The hostname or IP and port of the server, e.g. `http://127.0.0.1:7777`.
15//! * `verbosity_level` - When `1`, the JSON-RPC request will be printed to `stdout` with long
16//!   string fields (e.g. hex-formatted raw Wasm bytes) shortened to a string indicating the char
17//!   count of the field.  When `verbosity_level` is greater than `1`, the request will be printed
18//!   to `stdout` with no abbreviation of long fields.  When `verbosity_level` is `0`, the request
19//!   will not be printed to `stdout`.
20//! * `maybe_block_id` - Must be a hex-encoded, 32-byte hash digest or a `u64` representing the
21//!   [`Block`] height or empty.  If empty, the latest `Block` known on the server will be used.
22
23/// Functions for creating Deploys.
24mod arg_handling;
25pub mod deploy;
26mod deploy_builder;
27mod deploy_str_params;
28mod dictionary_item_str_params;
29mod error;
30mod fields_container;
31mod json_args;
32pub mod parse;
33mod payment_str_params;
34mod session_str_params;
35mod simple_args;
36#[cfg(test)]
37mod tests;
38mod transaction;
39mod transaction_builder_params;
40mod transaction_str_params;
41mod transaction_v1_builder;
42
43#[cfg(feature = "std-fs-io")]
44use serde::Serialize;
45
46#[cfg(doc)]
47use casper_types::account::AccountHash;
48
49use casper_types::{CLValue, Digest, Key, SystemHashRegistry, URef};
50
51use crate::{
52    rpcs::{
53        results::{
54            GetAccountResult, GetAddressableEntityResult, GetAuctionInfoResult, GetBalanceResult,
55            GetBlockResult, GetBlockTransfersResult, GetChainspecResult, GetDeployResult,
56            GetDictionaryItemResult, GetEraInfoResult, GetEraSummaryResult, GetNodeStatusResult,
57            GetPeersResult, GetRewardResult, GetStateRootHashResult, GetTransactionResult,
58            GetValidatorChangesResult, ListRpcsResult, QueryBalanceDetailsResult,
59            QueryBalanceResult, QueryGlobalStateResult,
60        },
61        DictionaryItemIdentifier,
62    },
63    SuccessResponse,
64};
65
66#[cfg(feature = "std-fs-io")]
67use crate::verification_types::VerificationDetails;
68#[cfg(doc)]
69use crate::{Account, Block, Error, StoredValue, Transfer};
70#[cfg(doc)]
71use casper_types::PublicKey;
72#[cfg(feature = "std-fs-io")]
73pub use deploy::{
74    make_deploy, make_transfer, put_deploy, put_deploy_with_min_bid_override, send_deploy_file,
75    sign_deploy_file, speculative_put_deploy, speculative_send_deploy_file, speculative_transfer,
76    transfer,
77};
78pub use deploy_builder::{DeployBuilder, DeployBuilderError};
79pub use deploy_str_params::DeployStrParams;
80pub use dictionary_item_str_params::DictionaryItemStrParams;
81pub use error::{CliError, FromDecStrErr};
82pub(crate) use fields_container::{FieldsContainer, FieldsContainerError};
83pub use json_args::{
84    help as json_args_help, Error as JsonArgsError, ErrorDetails as JsonArgsErrorDetails, JsonArg,
85};
86pub use parse::arg_simple::session::parse as arg_simple_session_parse;
87pub use parse::args_json::session::parse as arg_json_session_parse;
88pub use payment_str_params::PaymentStrParams;
89pub use session_str_params::SessionStrParams;
90pub use simple_args::{help as simple_args_help, insert_arg};
91pub use transaction::{get_maybe_secret_key, make_transaction, put_transaction};
92#[cfg(feature = "std-fs-io")]
93pub use transaction::{
94    send_transaction_file, sign_transaction_file, speculative_send_transaction_file,
95};
96pub use transaction_builder_params::TransactionBuilderParams;
97pub use transaction_str_params::TransactionStrParams;
98pub use transaction_v1_builder::{TransactionV1Builder, TransactionV1BuilderError};
99
100/// Retrieves a [`casper_types::Deploy`] from the network.
101///
102/// `deploy_hash` must be a hex-encoded, 32-byte hash digest.  For details of the other parameters,
103/// see [the module docs](crate::cli#common-parameters).
104pub async fn get_deploy(
105    maybe_rpc_id: &str,
106    node_address: &str,
107    verbosity_level: u64,
108    deploy_hash: &str,
109    finalized_approvals: bool,
110) -> Result<SuccessResponse<GetDeployResult>, CliError> {
111    let rpc_id = parse::rpc_id(maybe_rpc_id);
112    let verbosity = parse::verbosity(verbosity_level);
113    let deploy_hash = parse::deploy_hash(deploy_hash)?;
114    crate::get_deploy(
115        rpc_id,
116        node_address,
117        verbosity,
118        deploy_hash,
119        finalized_approvals,
120    )
121    .await
122    .map_err(CliError::from)
123}
124
125/// Retrieves a [`casper_types::Transaction`] from the network.
126///
127/// `transaction_hash` must be a hex-encoded, 32-byte hash digest.  For details of the other parameters,
128/// see [the module docs](crate::cli#common-parameters).
129pub async fn get_transaction(
130    maybe_rpc_id: &str,
131    node_address: &str,
132    verbosity_level: u64,
133    transaction_hash: &str,
134    finalized_approvals: bool,
135) -> Result<SuccessResponse<GetTransactionResult>, CliError> {
136    let rpc_id = parse::rpc_id(maybe_rpc_id);
137    let verbosity = parse::verbosity(verbosity_level);
138    let transaction_hash = parse::transaction_hash(transaction_hash)?;
139    crate::get_transaction(
140        rpc_id,
141        node_address,
142        verbosity,
143        transaction_hash,
144        finalized_approvals,
145    )
146    .await
147    .map_err(CliError::from)
148}
149/// Retrieves a [`Block`] from the network.
150///
151/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
152pub async fn get_block(
153    maybe_rpc_id: &str,
154    node_address: &str,
155    verbosity_level: u64,
156    maybe_block_id: &str,
157) -> Result<SuccessResponse<GetBlockResult>, CliError> {
158    let rpc_id = parse::rpc_id(maybe_rpc_id);
159    let verbosity = parse::verbosity(verbosity_level);
160    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
161    crate::get_block(rpc_id, node_address, verbosity, maybe_block_id)
162        .await
163        .map_err(CliError::from)
164}
165
166/// Retrieves all [`Transfer`] items for a [`Block`] from the network.
167///
168/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
169pub async fn get_block_transfers(
170    maybe_rpc_id: &str,
171    node_address: &str,
172    verbosity_level: u64,
173    maybe_block_id: &str,
174) -> Result<SuccessResponse<GetBlockTransfersResult>, CliError> {
175    let rpc_id = parse::rpc_id(maybe_rpc_id);
176    let verbosity = parse::verbosity(verbosity_level);
177    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
178    crate::get_block_transfers(rpc_id, node_address, verbosity, maybe_block_id)
179        .await
180        .map_err(CliError::from)
181}
182
183/// Retrieves a state root hash at a given [`Block`].
184///
185/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
186pub async fn get_state_root_hash(
187    maybe_rpc_id: &str,
188    node_address: &str,
189    verbosity_level: u64,
190    maybe_block_id: &str,
191) -> Result<SuccessResponse<GetStateRootHashResult>, CliError> {
192    let rpc_id = parse::rpc_id(maybe_rpc_id);
193    let verbosity = parse::verbosity(verbosity_level);
194    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
195    crate::get_state_root_hash(rpc_id, node_address, verbosity, maybe_block_id)
196        .await
197        .map_err(CliError::from)
198}
199
200/// Retrieves era information from the network at a given [`Block`].
201///
202/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
203pub async fn get_era_summary(
204    maybe_rpc_id: &str,
205    node_address: &str,
206    verbosity_level: u64,
207    maybe_block_id: &str,
208) -> Result<SuccessResponse<GetEraSummaryResult>, CliError> {
209    let rpc_id = parse::rpc_id(maybe_rpc_id);
210    let verbosity = parse::verbosity(verbosity_level);
211    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
212    crate::get_era_summary(rpc_id, node_address, verbosity, maybe_block_id)
213        .await
214        .map_err(CliError::from)
215}
216
217/// Retrieves a [`StoredValue`] from global state.
218///
219/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
220/// the query.  Exactly one of these args should be an empty string.
221///
222/// `key` must be a formatted [`PublicKey`] or [`Key`].  `path` is comprised of components starting
223/// from the `key`, separated by `/`s.  It may be empty.
224///
225/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
226pub async fn query_global_state(
227    maybe_rpc_id: &str,
228    node_address: &str,
229    verbosity_level: u64,
230    maybe_block_id: &str,
231    maybe_state_root_hash: &str,
232    key: &str,
233    path: &str,
234) -> Result<SuccessResponse<QueryGlobalStateResult>, CliError> {
235    let rpc_id = parse::rpc_id(maybe_rpc_id);
236    let verbosity = parse::verbosity(verbosity_level);
237    let global_state_identifier =
238        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?
239            .ok_or(CliError::FailedToParseStateIdentifier)?;
240    let key = parse::key_for_query(key)?;
241    let path = if path.is_empty() {
242        vec![]
243    } else {
244        path.split('/').map(ToString::to_string).collect()
245    };
246
247    crate::query_global_state(
248        rpc_id,
249        node_address,
250        verbosity,
251        global_state_identifier,
252        key,
253        path,
254    )
255    .await
256    .map_err(CliError::from)
257}
258
259/// Retrieves a purse's balance from global state.
260///
261/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
262/// the query.  If both are empty, the latest block is used.
263///
264/// `purse_id` can be a properly-formatted public key, account hash, entity address or URef.
265///
266/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
267pub async fn query_balance(
268    maybe_rpc_id: &str,
269    node_address: &str,
270    verbosity_level: u64,
271    maybe_block_id: &str,
272    maybe_state_root_hash: &str,
273    purse_id: &str,
274) -> Result<SuccessResponse<QueryBalanceResult>, CliError> {
275    let rpc_id = parse::rpc_id(maybe_rpc_id);
276    let verbosity = parse::verbosity(verbosity_level);
277    let maybe_global_state_identifier =
278        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?;
279    let purse_identifier = parse::purse_identifier(purse_id)?;
280
281    crate::query_balance(
282        rpc_id,
283        node_address,
284        verbosity,
285        maybe_global_state_identifier,
286        purse_identifier,
287    )
288    .await
289    .map_err(CliError::from)
290}
291
292/// Retrieves a purse's balance and hold information from global state.
293///
294/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
295/// the query.  If both are empty, the latest block is used.
296///
297/// `purse_id` can be a properly-formatted public key, account hash, entity address or URef.
298///
299/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
300pub async fn query_balance_details(
301    maybe_rpc_id: &str,
302    node_address: &str,
303    verbosity_level: u64,
304    maybe_block_id: &str,
305    maybe_state_root_hash: &str,
306    purse_id: &str,
307) -> Result<SuccessResponse<QueryBalanceDetailsResult>, CliError> {
308    let rpc_id = parse::rpc_id(maybe_rpc_id);
309    let verbosity = parse::verbosity(verbosity_level);
310    let maybe_global_state_identifier =
311        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?;
312    let purse_identifier = parse::purse_identifier(purse_id)?;
313
314    crate::query_balance_details(
315        rpc_id,
316        node_address,
317        verbosity,
318        maybe_global_state_identifier,
319        purse_identifier,
320    )
321    .await
322    .map_err(CliError::from)
323}
324
325/// Retrieves a [`StoredValue`] from a dictionary at a given state root hash.
326///
327/// `state_root_hash` must be a hex-encoded, 32-byte hash digest.
328///
329/// `dictionary_item_str_params` contains dictionary item identifier options for this query.  See
330/// [`DictionaryItemStrParams`] for more details.
331///
332/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
333pub async fn get_dictionary_item(
334    maybe_rpc_id: &str,
335    node_address: &str,
336    verbosity_level: u64,
337    state_root_hash: &str,
338    dictionary_item_str_params: DictionaryItemStrParams<'_>,
339) -> Result<SuccessResponse<GetDictionaryItemResult>, CliError> {
340    let rpc_id = parse::rpc_id(maybe_rpc_id);
341    let verbosity = parse::verbosity(verbosity_level);
342    let state_root_hash =
343        Digest::from_hex(state_root_hash).map_err(|error| CliError::FailedToParseDigest {
344            context: "state root hash in get_dictionary_item",
345            error,
346        })?;
347    let dictionary_item_identifier =
348        DictionaryItemIdentifier::try_from(dictionary_item_str_params)?;
349
350    crate::get_dictionary_item(
351        rpc_id,
352        node_address,
353        verbosity,
354        state_root_hash,
355        dictionary_item_identifier,
356    )
357    .await
358    .map_err(CliError::from)
359}
360
361/// Retrieves a purse's balance at a given state root hash.
362///
363/// `state_root_hash` must be a hex-encoded, 32-byte hash digest.
364///
365/// `purse` is a URef, formatted as e.g.
366/// ```text
367/// uref-0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20-007
368/// ```
369///
370/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
371pub async fn get_balance(
372    maybe_rpc_id: &str,
373    node_address: &str,
374    verbosity_level: u64,
375    state_root_hash: &str,
376    purse: &str,
377) -> Result<SuccessResponse<GetBalanceResult>, CliError> {
378    let rpc_id = parse::rpc_id(maybe_rpc_id);
379    let verbosity = parse::verbosity(verbosity_level);
380    let state_root_hash =
381        Digest::from_hex(state_root_hash).map_err(|error| CliError::FailedToParseDigest {
382            context: "state root hash in get_balance",
383            error,
384        })?;
385    let purse = URef::from_formatted_str(purse).map_err(|error| CliError::FailedToParseURef {
386        context: "purse in get_balance",
387        error,
388    })?;
389
390    crate::get_balance(rpc_id, node_address, verbosity, state_root_hash, purse)
391        .await
392        .map_err(CliError::from)
393}
394
395/// Retrieves an [`Account`] at a given [`Block`].
396///
397/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
398///
399/// # Parameters
400/// - `maybe_rpc_id`: The optional RPC ID as a string slice.
401/// - `node_address`: The address of the node as a string slice.
402/// - `verbosity_level`: The verbosity level as a 64-bit unsigned integer.
403/// - `maybe_block_id`: The optional block ID as a string slice.
404/// - `account_identifier`: The account identifier as a string slice.
405///
406/// # Returns
407/// The result containing either a successful response with the account details or a `CliError`.
408pub async fn get_account(
409    maybe_rpc_id: &str,
410    node_address: &str,
411    verbosity_level: u64,
412    maybe_block_id: &str,
413    account_identifier: &str,
414) -> Result<SuccessResponse<GetAccountResult>, CliError> {
415    let rpc_id = parse::rpc_id(maybe_rpc_id);
416    let verbosity = parse::verbosity(verbosity_level);
417    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
418    let account_identifier = parse::account_identifier(account_identifier)?;
419
420    crate::get_account(
421        rpc_id,
422        node_address,
423        verbosity,
424        maybe_block_id,
425        account_identifier,
426    )
427    .await
428    .map_err(CliError::from)
429}
430
431/// Retrieves an [`crate::rpcs::v2_0_0::get_entity::EntityOrAccount`] at a given [`Block`].
432///
433/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
434///
435/// # Parameters
436/// - `maybe_rpc_id`: The optional RPC ID as a string slice.
437/// - `node_address`: The address of the node as a string slice.
438/// - `verbosity_level`: The verbosity level as a 64-bit unsigned integer.
439/// - `maybe_block_id`: The optional block ID as a string slice.
440/// - `entity_identifier`: The entity identifier as a string slice.
441///
442/// # Returns
443/// The result containing either a successful response with the entity details or a `CliError`.
444pub async fn get_entity(
445    maybe_rpc_id: &str,
446    node_address: &str,
447    verbosity_level: u64,
448    maybe_block_id: &str,
449    entity_identifier: &str,
450) -> Result<SuccessResponse<GetAddressableEntityResult>, CliError> {
451    let rpc_id = parse::rpc_id(maybe_rpc_id);
452    let verbosity = parse::verbosity(verbosity_level);
453    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
454    let entity_identifier = parse::entity_identifier(entity_identifier)?;
455
456    crate::get_entity(
457        rpc_id,
458        node_address,
459        verbosity,
460        maybe_block_id,
461        entity_identifier,
462    )
463    .await
464    .map_err(CliError::from)
465}
466
467/// Retrieves an [`GetRewardResult`] at a given era.
468///
469/// `validator` is the public key as a formatted string associated with the validator.
470///
471/// `maybe_delegator` is the public key as a formatted string associated with the delegator.
472///
473/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
474pub async fn get_reward(
475    maybe_rpc_id: &str,
476    node_address: &str,
477    verbosity_level: u64,
478    maybe_era_id: &str,
479    validator: &str,
480    maybe_delegator: &str,
481) -> Result<SuccessResponse<GetRewardResult>, CliError> {
482    let rpc_id = parse::rpc_id(maybe_rpc_id);
483    let verbosity = parse::verbosity(verbosity_level);
484    let era_identifier = parse::era_identifier(maybe_era_id)?;
485    let validator =
486        parse::public_key(validator)?.ok_or(CliError::FailedToParseValidatorPublicKey)?;
487    let delegator = parse::public_key(maybe_delegator)?;
488
489    crate::get_reward(
490        rpc_id,
491        node_address,
492        verbosity,
493        era_identifier,
494        validator,
495        delegator,
496    )
497    .await
498    .map_err(CliError::from)
499}
500
501/// Retrieves the bids and validators at a given [`Block`].
502///
503/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
504pub async fn get_auction_info(
505    maybe_rpc_id: &str,
506    node_address: &str,
507    verbosity_level: u64,
508    maybe_block_id: &str,
509) -> Result<SuccessResponse<GetAuctionInfoResult>, CliError> {
510    let rpc_id = parse::rpc_id(maybe_rpc_id);
511    let verbosity = parse::verbosity(verbosity_level);
512    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
513    crate::get_auction_info(rpc_id, node_address, verbosity, maybe_block_id)
514        .await
515        .map_err(CliError::from)
516}
517
518/// Retrieve the system hash registry
519pub async fn get_system_hash_registry(
520    node_address: &str,
521    verbosity_level: u64,
522    state_root_hash: &str,
523) -> Result<SystemHashRegistry, CliError> {
524    let key = Key::SystemEntityRegistry.to_formatted_string();
525    let response = query_global_state(
526        "",
527        node_address,
528        verbosity_level,
529        "",
530        state_root_hash,
531        &key,
532        "",
533    )
534    .await?
535    .result
536    .stored_value
537    .into_cl_value()
538    .ok_or_else(|| CliError::FailedToGetSystemHashRegistry)?;
539
540    CLValue::to_t::<SystemHashRegistry>(&response)
541        .map_err(|err| CliError::InvalidCLValue(err.to_string()))
542}
543
544/// Retrieves the status changes of the active validators on the network.
545///
546/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
547pub async fn get_validator_changes(
548    maybe_rpc_id: &str,
549    node_address: &str,
550    verbosity_level: u64,
551) -> Result<SuccessResponse<GetValidatorChangesResult>, CliError> {
552    let rpc_id = parse::rpc_id(maybe_rpc_id);
553    let verbosity = parse::verbosity(verbosity_level);
554    crate::get_validator_changes(rpc_id, node_address, verbosity)
555        .await
556        .map_err(CliError::from)
557}
558
559/// Retrieves the IDs and addresses of the specified node's peers.
560///
561/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
562pub async fn get_peers(
563    maybe_rpc_id: &str,
564    node_address: &str,
565    verbosity_level: u64,
566) -> Result<SuccessResponse<GetPeersResult>, CliError> {
567    let rpc_id = parse::rpc_id(maybe_rpc_id);
568    let verbosity = parse::verbosity(verbosity_level);
569    crate::get_peers(rpc_id, node_address, verbosity)
570        .await
571        .map_err(CliError::from)
572}
573
574/// Retrieves the status of the specified node.
575///
576/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
577pub async fn get_node_status(
578    maybe_rpc_id: &str,
579    node_address: &str,
580    verbosity_level: u64,
581) -> Result<SuccessResponse<GetNodeStatusResult>, CliError> {
582    let rpc_id = parse::rpc_id(maybe_rpc_id);
583    let verbosity = parse::verbosity(verbosity_level);
584    crate::get_node_status(rpc_id, node_address, verbosity)
585        .await
586        .map_err(CliError::from)
587}
588
589/// Retrieves the Chainspec of the network.
590///
591/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
592pub async fn get_chainspec(
593    maybe_rpc_id: &str,
594    node_address: &str,
595    verbosity_level: u64,
596) -> Result<SuccessResponse<GetChainspecResult>, CliError> {
597    let rpc_id = parse::rpc_id(maybe_rpc_id);
598    let verbosity = parse::verbosity(verbosity_level);
599    crate::get_chainspec(rpc_id, node_address, verbosity)
600        .await
601        .map_err(CliError::from)
602}
603
604/// Retrieves the interface description (the schema including examples in OpenRPC format) of the
605/// JSON-RPC server's API.
606///
607/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
608pub async fn list_rpcs(
609    maybe_rpc_id: &str,
610    node_address: &str,
611    verbosity_level: u64,
612) -> Result<SuccessResponse<ListRpcsResult>, CliError> {
613    let rpc_id = parse::rpc_id(maybe_rpc_id);
614    let verbosity = parse::verbosity(verbosity_level);
615    crate::list_rpcs(rpc_id, node_address, verbosity)
616        .await
617        .map_err(CliError::from)
618}
619
620/// JSON-encode and pretty-print the given value to stdout at the given verbosity level.
621///
622/// When `verbosity_level` is `0`, nothing is printed.  For `1`, the value is printed with long
623/// string fields shortened to a string indicating the character count of the field.  Greater than
624/// `1` is the same as for `1` except without abbreviation of long fields.
625#[cfg(feature = "std-fs-io")]
626pub fn json_pretty_print<T: ?Sized + Serialize>(
627    value: &T,
628    verbosity_level: u64,
629) -> Result<(), CliError> {
630    let verbosity = parse::verbosity(verbosity_level);
631    crate::json_pretty_print(value, verbosity).map_err(CliError::from)
632}
633
634/// Retrieves era information from the network at a given switch [`Block`].
635///
636/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
637#[deprecated(
638    since = "2.0.0",
639    note = "prefer 'get_era_summary' as it doesn't require a switch block"
640)]
641pub async fn get_era_info(
642    maybe_rpc_id: &str,
643    node_address: &str,
644    verbosity_level: u64,
645    maybe_block_id: &str,
646) -> Result<SuccessResponse<GetEraInfoResult>, CliError> {
647    let rpc_id = parse::rpc_id(maybe_rpc_id);
648    let verbosity = parse::verbosity(verbosity_level);
649    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
650    #[allow(deprecated)]
651    crate::get_era_info(rpc_id, node_address, verbosity, maybe_block_id)
652        .await
653        .map_err(CliError::from)
654}
655
656/// Verifies the smart contract code against the one installed
657/// by deploy or transaction with given hash.
658#[cfg(feature = "std-fs-io")]
659pub async fn verify_contract(
660    hash_str: &str,
661    verification_url_base_path: &str,
662    verification_project_path: Option<&str>,
663    verbosity_level: u64,
664) -> Result<VerificationDetails, CliError> {
665    let verbosity = parse::verbosity(verbosity_level);
666    crate::verify_contract(
667        hash_str,
668        verification_url_base_path,
669        verification_project_path,
670        verbosity,
671    )
672    .await
673    .map_err(CliError::from)
674}