Skip to main content

sui_rpc_api/
read_mask_defaults.rs

1// Copyright (c) Mysten Labs, Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use sui_rpc::field::FieldMask;
5use sui_rpc::field::FieldMaskTree;
6use sui_rpc::field::FieldMaskUtil;
7use sui_rpc::field::MessageFields;
8use sui_rpc::proto::google::rpc::bad_request::FieldViolation;
9
10use crate::ErrorReason;
11use crate::RpcError;
12
13/// Default read mask for a transaction (`get_transaction`, `list_transactions`).
14pub const TRANSACTION: &str = "digest";
15
16/// Default read mask for a checkpoint (`get_checkpoint`, `list_checkpoints`).
17pub const CHECKPOINT: &str = "sequence_number,digest";
18
19/// Default read mask for an event (`list_events`; there is no `get_events`).
20pub const EVENT: &str = "event_type";
21
22/// Default read mask for an epoch (`get_epoch`; there is no `list_epochs`).
23pub const EPOCH: &str = "epoch,first_checkpoint,last_checkpoint,start,end,reference_gas_price,protocol_config.protocol_version";
24
25/// Default read mask for an object (`get_object`).
26pub const OBJECT: &str = "object_id,version,digest";
27
28/// Default read mask for an owned-object listing (`list_owned_objects`).
29pub const OWNED_OBJECT: &str = "object_id,version,object_type";
30
31/// Default read mask for a dynamic-field listing (`list_dynamic_fields`).
32pub const DYNAMIC_FIELD: &str = "parent,field_id";
33
34/// Default read mask for transaction execution (`ExecuteTransaction`).
35pub const EXECUTE_TRANSACTION: &str = "effects";
36
37/// Validate an optional request `read_mask` against message type `M`, falling
38/// back to `default` when the request omits one, and return it as a
39/// `FieldMaskTree`. Shared by every read-mask-bearing handler (get, list, and
40/// subscribe) so validation and the "no mask -> default" rule stay identical
41/// across them. `default` is an explicit argument because one message type can
42/// carry different per-endpoint defaults (e.g. `ExecutedTransaction` uses
43/// `TRANSACTION` for get/list but `EXECUTE_TRANSACTION` for execution).
44pub fn validate_read_mask<M: MessageFields>(
45    read_mask: Option<FieldMask>,
46    default: &str,
47) -> Result<FieldMaskTree, RpcError> {
48    let read_mask = read_mask.unwrap_or_else(|| FieldMask::from_str(default));
49    read_mask.validate::<M>().map_err(|path| {
50        FieldViolation::new("read_mask")
51            .with_description(format!("invalid read_mask path: {path}"))
52            .with_reason(ErrorReason::FieldInvalid)
53    })?;
54    Ok(FieldMaskTree::from(read_mask))
55}