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/// Deploy module.
24pub mod deploy;
25mod deploy_str_params;
26mod dictionary_item_str_params;
27mod error;
28mod json_args;
29mod parse;
30mod payment_str_params;
31mod session_str_params;
32mod simple_args;
33#[cfg(test)]
34mod tests;
35
36use serde::Serialize;
37
38use casper_hashing::Digest;
39#[cfg(doc)]
40use casper_types::{account::AccountHash, Key};
41use casper_types::{crypto, AsymmetricType, PublicKey, URef};
42
43use crate::{
44    rpcs::{
45        results::{
46            GetAccountResult, GetAuctionInfoResult, GetBalanceResult, GetBlockResult,
47            GetBlockTransfersResult, GetChainspecResult, GetDeployResult, GetDictionaryItemResult,
48            GetEraInfoResult, GetEraSummaryResult, GetNodeStatusResult, GetPeersResult,
49            GetStateRootHashResult, GetValidatorChangesResult, ListRpcsResult, PutDeployResult,
50            QueryBalanceResult, QueryGlobalStateResult, SpeculativeExecResult,
51        },
52        DictionaryItemIdentifier,
53    },
54    SuccessResponse,
55};
56#[cfg(doc)]
57use crate::{Account, Block, Deploy, Error, StoredValue, Transfer};
58pub use deploy_str_params::DeployStrParams;
59pub use dictionary_item_str_params::DictionaryItemStrParams;
60pub use error::CliError;
61use json_args::JsonArg;
62pub use json_args::{
63    help as json_args_help, Error as JsonArgsError, ErrorDetails as JsonArgsErrorDetails,
64};
65pub use payment_str_params::PaymentStrParams;
66pub use session_str_params::SessionStrParams;
67pub use simple_args::help as simple_args_help;
68
69/// Creates a [`Deploy`] and sends it to the network for execution.
70///
71/// For details of the parameters, see [the module docs](crate::cli#common-parameters) or the docs
72/// of the individual parameter types.
73pub async fn put_deploy(
74    maybe_rpc_id: &str,
75    node_address: &str,
76    verbosity_level: u64,
77    deploy_params: DeployStrParams<'_>,
78    session_params: SessionStrParams<'_>,
79    payment_params: PaymentStrParams<'_>,
80) -> Result<SuccessResponse<PutDeployResult>, CliError> {
81    let rpc_id = parse::rpc_id(maybe_rpc_id);
82    let verbosity = parse::verbosity(verbosity_level);
83    let deploy = deploy::with_payment_and_session(deploy_params, payment_params, session_params)?;
84    crate::put_deploy(rpc_id, node_address, verbosity, deploy)
85        .await
86        .map_err(CliError::from)
87}
88
89/// Creates a [`Deploy`] and sends it to the specified node for speculative execution.
90///
91/// For details of the parameters, see [the module docs](crate::cli#common-parameters) or the docs
92/// of the individual parameter types.
93pub async fn speculative_put_deploy(
94    maybe_block_id: &str,
95    maybe_rpc_id: &str,
96    node_address: &str,
97    verbosity_level: u64,
98    deploy_params: DeployStrParams<'_>,
99    session_params: SessionStrParams<'_>,
100    payment_params: PaymentStrParams<'_>,
101) -> Result<SuccessResponse<SpeculativeExecResult>, CliError> {
102    let rpc_id = parse::rpc_id(maybe_rpc_id);
103    let verbosity = parse::verbosity(verbosity_level);
104    let deploy = deploy::with_payment_and_session(deploy_params, payment_params, session_params)?;
105    let speculative_exec = parse::block_identifier(maybe_block_id)?;
106    crate::speculative_exec(rpc_id, node_address, speculative_exec, verbosity, deploy)
107        .await
108        .map_err(CliError::from)
109}
110/// Creates a [`Deploy`] and outputs it to a file or stdout.
111///
112/// As a file, the `Deploy` can subsequently be signed by other parties using [`sign_deploy_file`]
113/// and then sent to the network for execution using [`send_deploy_file`].
114///
115/// `maybe_output_path` specifies the output file path, or if empty, will print it to `stdout`.  If
116/// `force` is true, and a file exists at `maybe_output_path`, it will be overwritten.  If `force`
117/// is false and a file exists at `maybe_output_path`, [`Error::FileAlreadyExists`] is returned
118/// and the file will not be written.
119pub fn make_deploy(
120    maybe_output_path: &str,
121    deploy_params: DeployStrParams<'_>,
122    session_params: SessionStrParams<'_>,
123    payment_params: PaymentStrParams<'_>,
124    force: bool,
125) -> Result<(), CliError> {
126    let output = parse::output_kind(maybe_output_path, force);
127    let deploy = deploy::with_payment_and_session(deploy_params, payment_params, session_params)?;
128    crate::output_deploy(output, &deploy).map_err(CliError::from)
129}
130
131/// Reads a previously-saved [`Deploy`] from a file, cryptographically signs it, and outputs it to a
132/// file or stdout.
133///
134/// `maybe_output_path` specifies the output file path, or if empty, will print it to `stdout`.  If
135/// `force` is true, and a file exists at `maybe_output_path`, it will be overwritten.  If `force`
136/// is false and a file exists at `maybe_output_path`, [`Error::FileAlreadyExists`] is returned
137/// and the file will not be written.
138pub fn sign_deploy_file(
139    input_path: &str,
140    secret_key_path: &str,
141    maybe_output_path: &str,
142    force: bool,
143) -> Result<(), CliError> {
144    let secret_key = parse::secret_key_from_file(secret_key_path)?;
145    let output = parse::output_kind(maybe_output_path, force);
146    crate::sign_deploy_file(input_path, &secret_key, output).map_err(CliError::from)
147}
148
149/// Reads a previously-saved [`Deploy`] from a file and sends it to the network for execution.
150///
151/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
152pub async fn send_deploy_file(
153    maybe_rpc_id: &str,
154    node_address: &str,
155    verbosity_level: u64,
156    input_path: &str,
157) -> Result<SuccessResponse<PutDeployResult>, CliError> {
158    let rpc_id = parse::rpc_id(maybe_rpc_id);
159    let verbosity = parse::verbosity(verbosity_level);
160    let deploy = crate::read_deploy_file(input_path)?;
161    crate::put_deploy(rpc_id, node_address, verbosity, deploy)
162        .await
163        .map_err(CliError::from)
164}
165
166/// Reads a previously-saved [`Deploy`] from a file and sends it to the specified node for
167/// speculative execution.
168/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
169pub async fn speculative_send_deploy_file(
170    maybe_block_id: &str,
171    maybe_rpc_id: &str,
172    node_address: &str,
173    verbosity_level: u64,
174    input_path: &str,
175) -> Result<SuccessResponse<SpeculativeExecResult>, CliError> {
176    let rpc_id = parse::rpc_id(maybe_rpc_id);
177    let speculative_exec = parse::block_identifier(maybe_block_id)?;
178    let verbosity = parse::verbosity(verbosity_level);
179    let deploy = crate::read_deploy_file(input_path)?;
180    crate::speculative_exec(rpc_id, node_address, speculative_exec, verbosity, deploy)
181        .await
182        .map_err(CliError::from)
183}
184
185/// Transfers funds between purses.
186///
187/// * `amount` is a string to be parsed as a `U512` specifying the amount to be transferred.
188/// * `target_account` is the [`AccountHash`], [`URef`] or [`PublicKey`] of the account to which the
189///   funds will be transferred, formatted as a hex-encoded string.  The account's main purse will
190///   receive the funds.
191/// * `transfer_id` is a string to be parsed as a `u64` representing a user-defined identifier which
192///   will be permanently associated with the transfer.
193///
194/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
195#[allow(clippy::too_many_arguments)]
196pub async fn transfer(
197    maybe_rpc_id: &str,
198    node_address: &str,
199    verbosity_level: u64,
200    amount: &str,
201    target_account: &str,
202    transfer_id: &str,
203    deploy_params: DeployStrParams<'_>,
204    payment_params: PaymentStrParams<'_>,
205) -> Result<SuccessResponse<PutDeployResult>, CliError> {
206    let rpc_id = parse::rpc_id(maybe_rpc_id);
207    let verbosity = parse::verbosity(verbosity_level);
208    let deploy = deploy::new_transfer(
209        amount,
210        None,
211        target_account,
212        transfer_id,
213        deploy_params,
214        payment_params,
215    )?;
216    crate::put_deploy(rpc_id, node_address, verbosity, deploy)
217        .await
218        .map_err(CliError::from)
219}
220
221/// Creates a [`Deploy`] to transfer funds between purses, and sends it to the specified node for
222/// speculative execution.
223///
224/// * `amount` is a string to be parsed as a `U512` specifying the amount to be transferred.
225/// * `target_account` is the [`AccountHash`], [`URef`] or [`PublicKey`] of the account to which the
226///   funds will be transferred, formatted as a hex-encoded string.  The account's main purse will
227///   receive the funds.
228/// * `transfer_id` is a string to be parsed as a `u64` representing a user-defined identifier which
229///   will be permanently associated with the transfer.
230///
231/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
232#[allow(clippy::too_many_arguments)]
233pub async fn speculative_transfer(
234    maybe_block_id: &str,
235    maybe_rpc_id: &str,
236    node_address: &str,
237    verbosity_level: u64,
238    amount: &str,
239    target_account: &str,
240    transfer_id: &str,
241    deploy_params: DeployStrParams<'_>,
242    payment_params: PaymentStrParams<'_>,
243) -> Result<SuccessResponse<SpeculativeExecResult>, CliError> {
244    let rpc_id = parse::rpc_id(maybe_rpc_id);
245    let verbosity = parse::verbosity(verbosity_level);
246    let deploy = deploy::new_transfer(
247        amount,
248        None,
249        target_account,
250        transfer_id,
251        deploy_params,
252        payment_params,
253    )?;
254    let speculative_exec = parse::block_identifier(maybe_block_id)?;
255    crate::speculative_exec(rpc_id, node_address, speculative_exec, verbosity, deploy)
256        .await
257        .map_err(CliError::from)
258}
259
260/// Creates a transfer [`Deploy`] and outputs it to a file or stdout.
261///
262/// As a file, the `Deploy` can subsequently be signed by other parties using [`sign_deploy_file`]
263/// and then sent to the network for execution using [`send_deploy_file`].
264///
265/// `maybe_output_path` specifies the output file path, or if empty, will print it to `stdout`.  If
266/// `force` is true, and a file exists at `maybe_output_path`, it will be overwritten.  If `force`
267/// is false and a file exists at `maybe_output_path`, [`Error::FileAlreadyExists`] is returned
268/// and the file will not be written.
269pub fn make_transfer(
270    maybe_output_path: &str,
271    amount: &str,
272    target_account: &str,
273    transfer_id: &str,
274    deploy_params: DeployStrParams<'_>,
275    payment_params: PaymentStrParams<'_>,
276    force: bool,
277) -> Result<(), CliError> {
278    let output = parse::output_kind(maybe_output_path, force);
279    let deploy = deploy::new_transfer(
280        amount,
281        None,
282        target_account,
283        transfer_id,
284        deploy_params,
285        payment_params,
286    )?;
287    crate::output_deploy(output, &deploy).map_err(CliError::from)
288}
289
290/// Retrieves a [`Deploy`] from the network.
291///
292/// `deploy_hash` must be a hex-encoded, 32-byte hash digest.  For details of the other parameters,
293/// see [the module docs](crate::cli#common-parameters).
294pub async fn get_deploy(
295    maybe_rpc_id: &str,
296    node_address: &str,
297    verbosity_level: u64,
298    deploy_hash: &str,
299) -> Result<SuccessResponse<GetDeployResult>, CliError> {
300    let rpc_id = parse::rpc_id(maybe_rpc_id);
301    let verbosity = parse::verbosity(verbosity_level);
302    let deploy_hash = parse::deploy_hash(deploy_hash)?;
303    crate::get_deploy(rpc_id, node_address, verbosity, deploy_hash, false)
304        .await
305        .map_err(CliError::from)
306}
307
308/// Retrieves a [`Block`] from the network.
309///
310/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
311pub async fn get_block(
312    maybe_rpc_id: &str,
313    node_address: &str,
314    verbosity_level: u64,
315    maybe_block_id: &str,
316) -> Result<SuccessResponse<GetBlockResult>, CliError> {
317    let rpc_id = parse::rpc_id(maybe_rpc_id);
318    let verbosity = parse::verbosity(verbosity_level);
319    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
320    crate::get_block(rpc_id, node_address, verbosity, maybe_block_id)
321        .await
322        .map_err(CliError::from)
323}
324
325/// Retrieves all [`Transfer`] items for a [`Block`] from the network.
326///
327/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
328pub async fn get_block_transfers(
329    maybe_rpc_id: &str,
330    node_address: &str,
331    verbosity_level: u64,
332    maybe_block_id: &str,
333) -> Result<SuccessResponse<GetBlockTransfersResult>, CliError> {
334    let rpc_id = parse::rpc_id(maybe_rpc_id);
335    let verbosity = parse::verbosity(verbosity_level);
336    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
337    crate::get_block_transfers(rpc_id, node_address, verbosity, maybe_block_id)
338        .await
339        .map_err(CliError::from)
340}
341
342/// Retrieves a state root hash at a given [`Block`].
343///
344/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
345pub async fn get_state_root_hash(
346    maybe_rpc_id: &str,
347    node_address: &str,
348    verbosity_level: u64,
349    maybe_block_id: &str,
350) -> Result<SuccessResponse<GetStateRootHashResult>, CliError> {
351    let rpc_id = parse::rpc_id(maybe_rpc_id);
352    let verbosity = parse::verbosity(verbosity_level);
353    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
354    crate::get_state_root_hash(rpc_id, node_address, verbosity, maybe_block_id)
355        .await
356        .map_err(CliError::from)
357}
358
359/// Retrieves era information from the network at a given [`Block`].
360///
361/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
362pub async fn get_era_summary(
363    maybe_rpc_id: &str,
364    node_address: &str,
365    verbosity_level: u64,
366    maybe_block_id: &str,
367) -> Result<SuccessResponse<GetEraSummaryResult>, CliError> {
368    let rpc_id = parse::rpc_id(maybe_rpc_id);
369    let verbosity = parse::verbosity(verbosity_level);
370    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
371    crate::get_era_summary(rpc_id, node_address, verbosity, maybe_block_id)
372        .await
373        .map_err(CliError::from)
374}
375
376/// Retrieves a [`StoredValue`] from global state.
377///
378/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
379/// the query.  Exactly one of these args should be an empty string.
380///
381/// `key` must be a formatted [`PublicKey`] or [`Key`].  `path` is comprised of components starting
382/// from the `key`, separated by `/`s.  It may be empty.
383///
384/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
385pub async fn query_global_state(
386    maybe_rpc_id: &str,
387    node_address: &str,
388    verbosity_level: u64,
389    maybe_block_id: &str,
390    maybe_state_root_hash: &str,
391    key: &str,
392    path: &str,
393) -> Result<SuccessResponse<QueryGlobalStateResult>, CliError> {
394    let rpc_id = parse::rpc_id(maybe_rpc_id);
395    let verbosity = parse::verbosity(verbosity_level);
396    let global_state_identifier =
397        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?
398            .ok_or(CliError::FailedToParseStateIdentifier)?;
399    let key = parse::key_for_query(key)?;
400    let path = if path.is_empty() {
401        vec![]
402    } else {
403        path.split('/').map(ToString::to_string).collect()
404    };
405
406    crate::query_global_state(
407        rpc_id,
408        node_address,
409        verbosity,
410        global_state_identifier,
411        key,
412        path,
413    )
414    .await
415    .map_err(CliError::from)
416}
417
418/// Retrieves a purse's balance from global state.
419///
420/// `maybe_block_id` or `maybe_state_root_hash` identify the global state root hash to be used for
421/// the query.  If both are empty, the latest block is used.
422///
423/// `purse_id` can be a properly-formatted public key, account hash or URef.
424///
425/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
426pub async fn query_balance(
427    maybe_rpc_id: &str,
428    node_address: &str,
429    verbosity_level: u64,
430    maybe_block_id: &str,
431    maybe_state_root_hash: &str,
432    purse_id: &str,
433) -> Result<SuccessResponse<QueryBalanceResult>, CliError> {
434    let rpc_id = parse::rpc_id(maybe_rpc_id);
435    let verbosity = parse::verbosity(verbosity_level);
436    let maybe_global_state_identifier =
437        parse::global_state_identifier(maybe_block_id, maybe_state_root_hash)?;
438    let purse_identifier = parse::purse_identifier(purse_id)?;
439
440    crate::query_balance(
441        rpc_id,
442        node_address,
443        verbosity,
444        maybe_global_state_identifier,
445        purse_identifier,
446    )
447    .await
448    .map_err(CliError::from)
449}
450
451/// Retrieves a [`StoredValue`] from a dictionary at a given state root hash.
452///
453/// `state_root_hash` must be a hex-encoded, 32-byte hash digest.
454///
455/// `dictionary_item_str_params` contains dictionary item identifier options for this query.  See
456/// [`DictionaryItemStrParams`] for more details.
457///
458/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
459pub async fn get_dictionary_item(
460    maybe_rpc_id: &str,
461    node_address: &str,
462    verbosity_level: u64,
463    state_root_hash: &str,
464    dictionary_item_str_params: DictionaryItemStrParams<'_>,
465) -> Result<SuccessResponse<GetDictionaryItemResult>, CliError> {
466    let rpc_id = parse::rpc_id(maybe_rpc_id);
467    let verbosity = parse::verbosity(verbosity_level);
468    let state_root_hash =
469        Digest::from_hex(state_root_hash).map_err(|error| CliError::FailedToParseDigest {
470            context: "state root hash in get_dictionary_item",
471            error,
472        })?;
473    let dictionary_item_identifier =
474        DictionaryItemIdentifier::try_from(dictionary_item_str_params)?;
475
476    crate::get_dictionary_item(
477        rpc_id,
478        node_address,
479        verbosity,
480        state_root_hash,
481        dictionary_item_identifier,
482    )
483    .await
484    .map_err(CliError::from)
485}
486
487/// Retrieves a purse's balance at a given state root hash.
488///
489/// `state_root_hash` must be a hex-encoded, 32-byte hash digest.
490///
491/// `purse` is a URef, formatted as e.g.
492/// ```text
493/// uref-0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20-007
494/// ```
495///
496/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
497pub async fn get_balance(
498    maybe_rpc_id: &str,
499    node_address: &str,
500    verbosity_level: u64,
501    state_root_hash: &str,
502    purse: &str,
503) -> Result<SuccessResponse<GetBalanceResult>, CliError> {
504    let rpc_id = parse::rpc_id(maybe_rpc_id);
505    let verbosity = parse::verbosity(verbosity_level);
506    let state_root_hash =
507        Digest::from_hex(state_root_hash).map_err(|error| CliError::FailedToParseDigest {
508            context: "state root hash in get_balance",
509            error,
510        })?;
511    let purse = URef::from_formatted_str(purse).map_err(|error| CliError::FailedToParseURef {
512        context: "purse in get_balance",
513        error,
514    })?;
515
516    crate::get_balance(rpc_id, node_address, verbosity, state_root_hash, purse)
517        .await
518        .map_err(CliError::from)
519}
520
521/// Retrieves an [`Account`] at a given [`Block`].
522///
523/// `public_key` is the public key as a formatted string associated with the `Account`.
524///
525/// For details of other parameters, see [the module docs](crate::cli#common-parameters).
526pub async fn get_account(
527    maybe_rpc_id: &str,
528    node_address: &str,
529    verbosity_level: u64,
530    maybe_block_id: &str,
531    public_key: &str,
532) -> Result<SuccessResponse<GetAccountResult>, CliError> {
533    let rpc_id = parse::rpc_id(maybe_rpc_id);
534    let verbosity = parse::verbosity(verbosity_level);
535    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
536    let account_identifier =
537        PublicKey::from_hex(public_key).map_err(|error| crate::Error::CryptoError {
538            context: "public key in get_account",
539            error: crypto::ErrorExt::from(error),
540        })?;
541
542    crate::get_account(
543        rpc_id,
544        node_address,
545        verbosity,
546        maybe_block_id,
547        account_identifier,
548    )
549    .await
550    .map_err(CliError::from)
551}
552
553/// Retrieves the bids and validators at a given [`Block`].
554///
555/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
556pub async fn get_auction_info(
557    maybe_rpc_id: &str,
558    node_address: &str,
559    verbosity_level: u64,
560    maybe_block_id: &str,
561) -> Result<SuccessResponse<GetAuctionInfoResult>, CliError> {
562    let rpc_id = parse::rpc_id(maybe_rpc_id);
563    let verbosity = parse::verbosity(verbosity_level);
564    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
565    crate::get_auction_info(rpc_id, node_address, verbosity, maybe_block_id)
566        .await
567        .map_err(CliError::from)
568}
569
570/// Retrieves the status changes of the active validators on the network.
571///
572/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
573pub async fn get_validator_changes(
574    maybe_rpc_id: &str,
575    node_address: &str,
576    verbosity_level: u64,
577) -> Result<SuccessResponse<GetValidatorChangesResult>, CliError> {
578    let rpc_id = parse::rpc_id(maybe_rpc_id);
579    let verbosity = parse::verbosity(verbosity_level);
580    crate::get_validator_changes(rpc_id, node_address, verbosity)
581        .await
582        .map_err(CliError::from)
583}
584
585/// Retrieves the IDs and addresses of the specified node's peers.
586///
587/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
588pub async fn get_peers(
589    maybe_rpc_id: &str,
590    node_address: &str,
591    verbosity_level: u64,
592) -> Result<SuccessResponse<GetPeersResult>, CliError> {
593    let rpc_id = parse::rpc_id(maybe_rpc_id);
594    let verbosity = parse::verbosity(verbosity_level);
595    crate::get_peers(rpc_id, node_address, verbosity)
596        .await
597        .map_err(CliError::from)
598}
599
600/// Retrieves the status of the specified node.
601///
602/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
603pub async fn get_node_status(
604    maybe_rpc_id: &str,
605    node_address: &str,
606    verbosity_level: u64,
607) -> Result<SuccessResponse<GetNodeStatusResult>, CliError> {
608    let rpc_id = parse::rpc_id(maybe_rpc_id);
609    let verbosity = parse::verbosity(verbosity_level);
610    crate::get_node_status(rpc_id, node_address, verbosity)
611        .await
612        .map_err(CliError::from)
613}
614
615/// Retrieves the Chainspec of the network.
616///
617/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
618pub async fn get_chainspec(
619    maybe_rpc_id: &str,
620    node_address: &str,
621    verbosity_level: u64,
622) -> Result<SuccessResponse<GetChainspecResult>, CliError> {
623    let rpc_id = parse::rpc_id(maybe_rpc_id);
624    let verbosity = parse::verbosity(verbosity_level);
625    crate::get_chainspec(rpc_id, node_address, verbosity)
626        .await
627        .map_err(CliError::from)
628}
629
630/// Retrieves the interface description (the schema including examples in OpenRPC format) of the
631/// JSON-RPC server's API.
632///
633/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
634pub async fn list_rpcs(
635    maybe_rpc_id: &str,
636    node_address: &str,
637    verbosity_level: u64,
638) -> Result<SuccessResponse<ListRpcsResult>, CliError> {
639    let rpc_id = parse::rpc_id(maybe_rpc_id);
640    let verbosity = parse::verbosity(verbosity_level);
641    crate::list_rpcs(rpc_id, node_address, verbosity)
642        .await
643        .map_err(CliError::from)
644}
645
646/// JSON-encode and pretty-print the given value to stdout at the given verbosity level.
647///
648/// When `verbosity_level` is `0`, nothing is printed.  For `1`, the value is printed with long
649/// string fields shortened to a string indicating the character count of the field.  Greater than
650/// `1` is the same as for `1` except without abbreviation of long fields.
651pub fn json_pretty_print<T: ?Sized + Serialize>(
652    value: &T,
653    verbosity_level: u64,
654) -> Result<(), CliError> {
655    let verbosity = parse::verbosity(verbosity_level);
656    crate::json_pretty_print(value, verbosity).map_err(CliError::from)
657}
658
659/// Retrieves era information from the network at a given switch [`Block`].
660///
661/// For details of the parameters, see [the module docs](crate::cli#common-parameters).
662#[deprecated(
663    since = "2.0.0",
664    note = "prefer 'get_era_summary' as it doesn't require a switch block"
665)]
666pub async fn get_era_info(
667    maybe_rpc_id: &str,
668    node_address: &str,
669    verbosity_level: u64,
670    maybe_block_id: &str,
671) -> Result<SuccessResponse<GetEraInfoResult>, CliError> {
672    let rpc_id = parse::rpc_id(maybe_rpc_id);
673    let verbosity = parse::verbosity(verbosity_level);
674    let maybe_block_id = parse::block_identifier(maybe_block_id)?;
675    #[allow(deprecated)]
676    crate::get_era_info(rpc_id, node_address, verbosity, maybe_block_id)
677        .await
678        .map_err(CliError::from)
679}