Skip to main content

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    let key = parse::key_for_query(key)?;
240    let path = if path.is_empty() {
241        vec![]
242    } else {
243        path.split('/').map(ToString::to_string).collect()
244    };
245
246    crate::query_global_state(
247        rpc_id,
248        node_address,
249        verbosity,
250        global_state_identifier,
251        key,
252        path,
253    )
254    .await
255    .map_err(CliError::from)
256}
257
258/// Retrieves a purse's balance from global state.
259///
260/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
261/// the query.  If both are empty, the latest block is used.
262///
263/// `purse_id` can be a properly-formatted public key, account hash, entity address or URef.
264///
265/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
266pub async fn query_balance(
267    maybe_rpc_id: &str,
268    node_address: &str,
269    verbosity_level: u64,
270    maybe_block_id: &str,
271    maybe_state_root_hash: &str,
272    purse_id: &str,
273) -> Result<SuccessResponse<QueryBalanceResult>, CliError> {
274    let rpc_id = parse::rpc_id(maybe_rpc_id);
275    let verbosity = parse::verbosity(verbosity_level);
276    let maybe_global_state_identifier =
277        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?;
278    let purse_identifier = parse::purse_identifier(purse_id)?;
279
280    crate::query_balance(
281        rpc_id,
282        node_address,
283        verbosity,
284        maybe_global_state_identifier,
285        purse_identifier,
286    )
287    .await
288    .map_err(CliError::from)
289}
290
291/// Retrieves a purse's balance and hold information from global state.
292///
293/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
294/// the query.  If both are empty, the latest block is used.
295///
296/// `purse_id` can be a properly-formatted public key, account hash, entity address or URef.
297///
298/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
299pub async fn query_balance_details(
300    maybe_rpc_id: &str,
301    node_address: &str,
302    verbosity_level: u64,
303    maybe_block_id: &str,
304    maybe_state_root_hash: &str,
305    purse_id: &str,
306) -> Result<SuccessResponse<QueryBalanceDetailsResult>, CliError> {
307    let rpc_id = parse::rpc_id(maybe_rpc_id);
308    let verbosity = parse::verbosity(verbosity_level);
309    let maybe_global_state_identifier =
310        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?;
311    let purse_identifier = parse::purse_identifier(purse_id)?;
312
313    crate::query_balance_details(
314        rpc_id,
315        node_address,
316        verbosity,
317        maybe_global_state_identifier,
318        purse_identifier,
319    )
320    .await
321    .map_err(CliError::from)
322}
323
324/// Retrieves a [`StoredValue`] from a dictionary at a given state root hash.
325///
326/// `state_root_hash` must be a hex-encoded, 32-byte hash digest.
327///
328/// `dictionary_item_str_params` contains dictionary item identifier options for this query.  See
329/// [`DictionaryItemStrParams`] for more details.
330///
331/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
332pub async fn get_dictionary_item(
333    maybe_rpc_id: &str,
334    node_address: &str,
335    verbosity_level: u64,
336    state_root_hash: &str,
337    dictionary_item_str_params: DictionaryItemStrParams<'_>,
338) -> Result<SuccessResponse<GetDictionaryItemResult>, CliError> {
339    let rpc_id = parse::rpc_id(maybe_rpc_id);
340    let verbosity = parse::verbosity(verbosity_level);
341    let state_root_hash =
342        Digest::from_hex(state_root_hash).map_err(|error| CliError::FailedToParseDigest {
343            context: "state root hash in get_dictionary_item",
344            error,
345        })?;
346    let dictionary_item_identifier =
347        DictionaryItemIdentifier::try_from(dictionary_item_str_params)?;
348
349    crate::get_dictionary_item(
350        rpc_id,
351        node_address,
352        verbosity,
353        state_root_hash,
354        dictionary_item_identifier,
355    )
356    .await
357    .map_err(CliError::from)
358}
359
360/// Retrieves a purse's balance at a given state root hash.
361///
362/// `state_root_hash` must be a hex-encoded, 32-byte hash digest.
363///
364/// `purse` is a URef, formatted as e.g.
365/// ```text
366/// uref-0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20-007
367/// ```
368///
369/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
370pub async fn get_balance(
371    maybe_rpc_id: &str,
372    node_address: &str,
373    verbosity_level: u64,
374    state_root_hash: &str,
375    purse: &str,
376) -> Result<SuccessResponse<GetBalanceResult>, CliError> {
377    let rpc_id = parse::rpc_id(maybe_rpc_id);
378    let verbosity = parse::verbosity(verbosity_level);
379    let state_root_hash =
380        Digest::from_hex(state_root_hash).map_err(|error| CliError::FailedToParseDigest {
381            context: "state root hash in get_balance",
382            error,
383        })?;
384    let purse = URef::from_formatted_str(purse).map_err(|error| CliError::FailedToParseURef {
385        context: "purse in get_balance",
386        error,
387    })?;
388
389    crate::get_balance(rpc_id, node_address, verbosity, state_root_hash, purse)
390        .await
391        .map_err(CliError::from)
392}
393
394/// Retrieves an [`Account`] at a given [`Block`].
395///
396/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
397///
398/// # Parameters
399/// - `maybe_rpc_id`: The optional RPC ID as a string slice.
400/// - `node_address`: The address of the node as a string slice.
401/// - `verbosity_level`: The verbosity level as a 64-bit unsigned integer.
402/// - `maybe_block_id`: The optional block ID as a string slice.
403/// - `account_identifier`: The account identifier as a string slice.
404///
405/// # Returns
406/// The result containing either a successful response with the account details or a `CliError`.
407pub async fn get_account(
408    maybe_rpc_id: &str,
409    node_address: &str,
410    verbosity_level: u64,
411    maybe_block_id: &str,
412    account_identifier: &str,
413) -> Result<SuccessResponse<GetAccountResult>, CliError> {
414    let rpc_id = parse::rpc_id(maybe_rpc_id);
415    let verbosity = parse::verbosity(verbosity_level);
416    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
417    let account_identifier = parse::account_identifier(account_identifier)?;
418
419    crate::get_account(
420        rpc_id,
421        node_address,
422        verbosity,
423        maybe_block_id,
424        account_identifier,
425    )
426    .await
427    .map_err(CliError::from)
428}
429
430/// Retrieves an [`crate::rpcs::v2_0_0::get_entity::EntityOrAccount`] at a given [`Block`].
431///
432/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
433///
434/// # Parameters
435/// - `maybe_rpc_id`: The optional RPC ID as a string slice.
436/// - `node_address`: The address of the node as a string slice.
437/// - `verbosity_level`: The verbosity level as a 64-bit unsigned integer.
438/// - `maybe_block_id`: The optional block ID as a string slice.
439/// - `entity_identifier`: The entity identifier as a string slice.
440///
441/// # Returns
442/// The result containing either a successful response with the entity details or a `CliError`.
443pub async fn get_entity(
444    maybe_rpc_id: &str,
445    node_address: &str,
446    verbosity_level: u64,
447    maybe_block_id: &str,
448    entity_identifier: &str,
449) -> Result<SuccessResponse<GetAddressableEntityResult>, CliError> {
450    let rpc_id = parse::rpc_id(maybe_rpc_id);
451    let verbosity = parse::verbosity(verbosity_level);
452    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
453    let entity_identifier = parse::entity_identifier(entity_identifier)?;
454
455    crate::get_entity(
456        rpc_id,
457        node_address,
458        verbosity,
459        maybe_block_id,
460        entity_identifier,
461    )
462    .await
463    .map_err(CliError::from)
464}
465
466/// Retrieves an [`GetRewardResult`] at a given era.
467///
468/// `validator` is the public key as a formatted string associated with the validator.
469///
470/// `maybe_delegator` is the public key as a formatted string associated with the delegator.
471///
472/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
473pub async fn get_reward(
474    maybe_rpc_id: &str,
475    node_address: &str,
476    verbosity_level: u64,
477    maybe_era_id: &str,
478    validator: &str,
479    maybe_delegator: &str,
480) -> Result<SuccessResponse<GetRewardResult>, CliError> {
481    let rpc_id = parse::rpc_id(maybe_rpc_id);
482    let verbosity = parse::verbosity(verbosity_level);
483    let era_identifier = parse::era_identifier(maybe_era_id)?;
484    let validator =
485        parse::public_key(validator)?.ok_or(CliError::FailedToParseValidatorPublicKey)?;
486    let delegator = parse::public_key(maybe_delegator)?;
487
488    crate::get_reward(
489        rpc_id,
490        node_address,
491        verbosity,
492        era_identifier,
493        validator,
494        delegator,
495    )
496    .await
497    .map_err(CliError::from)
498}
499
500/// Retrieves the bids and validators at a given [`Block`].
501///
502/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
503pub async fn get_auction_info(
504    maybe_rpc_id: &str,
505    node_address: &str,
506    verbosity_level: u64,
507    maybe_block_id: &str,
508) -> Result<SuccessResponse<GetAuctionInfoResult>, CliError> {
509    let rpc_id = parse::rpc_id(maybe_rpc_id);
510    let verbosity = parse::verbosity(verbosity_level);
511    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
512    crate::get_auction_info(rpc_id, node_address, verbosity, maybe_block_id)
513        .await
514        .map_err(CliError::from)
515}
516
517/// Retrieve the system hash registry
518pub async fn get_system_hash_registry(
519    node_address: &str,
520    verbosity_level: u64,
521    state_root_hash: &str,
522) -> Result<SystemHashRegistry, CliError> {
523    let key = Key::SystemEntityRegistry.to_formatted_string();
524    let response = query_global_state(
525        "",
526        node_address,
527        verbosity_level,
528        "",
529        state_root_hash,
530        &key,
531        "",
532    )
533    .await?
534    .result
535    .stored_value
536    .into_cl_value()
537    .ok_or_else(|| CliError::FailedToGetSystemHashRegistry)?;
538
539    CLValue::to_t::<SystemHashRegistry>(&response)
540        .map_err(|err| CliError::InvalidCLValue(err.to_string()))
541}
542
543/// Retrieves the status changes of the active validators on the network.
544///
545/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
546pub async fn get_validator_changes(
547    maybe_rpc_id: &str,
548    node_address: &str,
549    verbosity_level: u64,
550) -> Result<SuccessResponse<GetValidatorChangesResult>, CliError> {
551    let rpc_id = parse::rpc_id(maybe_rpc_id);
552    let verbosity = parse::verbosity(verbosity_level);
553    crate::get_validator_changes(rpc_id, node_address, verbosity)
554        .await
555        .map_err(CliError::from)
556}
557
558/// Retrieves the IDs and addresses of the specified node's peers.
559///
560/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
561pub async fn get_peers(
562    maybe_rpc_id: &str,
563    node_address: &str,
564    verbosity_level: u64,
565) -> Result<SuccessResponse<GetPeersResult>, CliError> {
566    let rpc_id = parse::rpc_id(maybe_rpc_id);
567    let verbosity = parse::verbosity(verbosity_level);
568    crate::get_peers(rpc_id, node_address, verbosity)
569        .await
570        .map_err(CliError::from)
571}
572
573/// Retrieves the status of the specified node.
574///
575/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
576pub async fn get_node_status(
577    maybe_rpc_id: &str,
578    node_address: &str,
579    verbosity_level: u64,
580) -> Result<SuccessResponse<GetNodeStatusResult>, CliError> {
581    let rpc_id = parse::rpc_id(maybe_rpc_id);
582    let verbosity = parse::verbosity(verbosity_level);
583    crate::get_node_status(rpc_id, node_address, verbosity)
584        .await
585        .map_err(CliError::from)
586}
587
588/// Retrieves the Chainspec of the network.
589///
590/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
591pub async fn get_chainspec(
592    maybe_rpc_id: &str,
593    node_address: &str,
594    verbosity_level: u64,
595) -> Result<SuccessResponse<GetChainspecResult>, CliError> {
596    let rpc_id = parse::rpc_id(maybe_rpc_id);
597    let verbosity = parse::verbosity(verbosity_level);
598    crate::get_chainspec(rpc_id, node_address, verbosity)
599        .await
600        .map_err(CliError::from)
601}
602
603/// Retrieves the interface description (the schema including examples in OpenRPC format) of the
604/// JSON-RPC server's API.
605///
606/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
607pub async fn list_rpcs(
608    maybe_rpc_id: &str,
609    node_address: &str,
610    verbosity_level: u64,
611) -> Result<SuccessResponse<ListRpcsResult>, CliError> {
612    let rpc_id = parse::rpc_id(maybe_rpc_id);
613    let verbosity = parse::verbosity(verbosity_level);
614    crate::list_rpcs(rpc_id, node_address, verbosity)
615        .await
616        .map_err(CliError::from)
617}
618
619/// JSON-encode and pretty-print the given value to stdout at the given verbosity level.
620///
621/// When `verbosity_level` is `0`, nothing is printed.  For `1`, the value is printed with long
622/// string fields shortened to a string indicating the character count of the field.  Greater than
623/// `1` is the same as for `1` except without abbreviation of long fields.
624#[cfg(feature = "std-fs-io")]
625pub fn json_pretty_print<T: ?Sized + Serialize>(
626    value: &T,
627    verbosity_level: u64,
628) -> Result<(), CliError> {
629    let verbosity = parse::verbosity(verbosity_level);
630    crate::json_pretty_print(value, verbosity).map_err(CliError::from)
631}
632
633/// Retrieves era information from the network at a given switch [`Block`].
634///
635/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
636#[deprecated(
637    since = "2.0.0",
638    note = "prefer 'get_era_summary' as it doesn't require a switch block"
639)]
640pub async fn get_era_info(
641    maybe_rpc_id: &str,
642    node_address: &str,
643    verbosity_level: u64,
644    maybe_block_id: &str,
645) -> Result<SuccessResponse<GetEraInfoResult>, CliError> {
646    let rpc_id = parse::rpc_id(maybe_rpc_id);
647    let verbosity = parse::verbosity(verbosity_level);
648    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
649    #[allow(deprecated)]
650    crate::get_era_info(rpc_id, node_address, verbosity, maybe_block_id)
651        .await
652        .map_err(CliError::from)
653}
654
655/// Verifies the smart contract code against the one installed
656/// by deploy or transaction with given hash.
657#[cfg(feature = "std-fs-io")]
658pub async fn verify_contract(
659    hash_str: &str,
660    verification_url_base_path: &str,
661    verification_project_path: Option<&str>,
662    verbosity_level: u64,
663) -> Result<VerificationDetails, CliError> {
664    let verbosity = parse::verbosity(verbosity_level);
665    crate::verify_contract(
666        hash_str,
667        verification_url_base_path,
668        verification_project_path,
669        verbosity,
670    )
671    .await
672    .map_err(CliError::from)
673}