Skip to content

Commit

Permalink
sui-graphql-client: fix return of bcs and typetag in DynamicFieldOutp…
Browse files Browse the repository at this point in the history
…ut (#46)
  • Loading branch information
stefan-mysten authored Oct 25, 2024
1 parent 62f33cc commit 24207a2
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 15 deletions.
34 changes: 27 additions & 7 deletions crates/sui-graphql-client/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,12 @@ pub struct DynamicFieldName {
pub json: Option<serde_json::Value>,
}

type Typename = String;

#[derive(Debug)]
pub struct DynamicFieldOutput {
/// The name of the dynamic field
pub name: DynamicFieldName,
/// The dynamic field value typename and bcs
pub value: Option<(Typename, Vec<u8>)>,
pub value: Option<(TypeTag, Vec<u8>)>,
/// The json representation of the dynamic field value object
pub value_as_json: Option<serde_json::Value>,
}
Expand Down Expand Up @@ -191,19 +189,41 @@ impl From<BcsName> for NameValue {
}

impl DynamicFieldOutput {
pub fn deserialize<T: DeserializeOwned>(
/// Deserialize the name of the dynamic field into the specified type.
pub fn deserialize_name<T: DeserializeOwned>(
&self,
expected_type: TypeTag,
expected_type: &TypeTag,
) -> Result<T, anyhow::Error> {
assert_eq!(
expected_type, self.name.type_,
expected_type, &self.name.type_,
"Expected type {}, but got {}",
expected_type, self.name.type_
expected_type, &self.name.type_
);

let bcs = &self.name.bcs;
bcs::from_bytes::<T>(bcs).map_err(|_| anyhow!("Cannot decode BCS bytes"))
}

/// Deserialize the value of the dynamic field into the specified type.
pub fn deserialize_value<T: DeserializeOwned>(
&self,
expected_type: &TypeTag,
) -> Result<T, anyhow::Error> {
let typetag = self.value.as_ref().map(|(typename, _)| typename);
assert_eq!(
Some(&expected_type),
typetag.as_ref(),
"Expected type {}, but got {:?}",
expected_type,
typetag
);

if let Some((_, bcs)) = &self.value {
bcs::from_bytes::<T>(bcs).map_err(|_| anyhow!("Cannot decode BCS bytes"))
} else {
Err(anyhow!("No value found"))
}
}
}

/// The GraphQL client for interacting with the Sui blockchain.
Expand Down
19 changes: 11 additions & 8 deletions crates/sui-graphql-client/src/query_types/dynamic_fields.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,15 +135,18 @@ impl DynamicFieldValue {
}

/// Return the typename and bcs of this dynamic field value.
pub fn type_bcs(&self) -> Option<(String, Vec<u8>)> {
pub fn type_bcs(&self) -> Option<(TypeTag, Vec<u8>)> {
match self {
DynamicFieldValue::MoveObject(mo) => mo
.contents
.as_ref()
.map(|o| (o.type_.repr.clone(), o.bcs.0.clone().into())),
DynamicFieldValue::MoveValue(mv) => {
Some((mv.type_.repr.clone(), mv.bcs.0.clone().into()))
}
DynamicFieldValue::MoveObject(mo) => mo.contents.as_ref().map(|o| {
(
TypeTag::from_str(&o.type_.repr.clone()).expect("Invalid TypeTag"),
base64ct::Base64::decode_vec(&o.bcs.0).expect("Invalid Base64"),
)
}),
DynamicFieldValue::MoveValue(mv) => Some((
TypeTag::from_str(&mv.type_.repr.clone()).expect("Invalid TypeTag"),
base64ct::Base64::decode_vec(&mv.bcs.0).expect("Invalid Base64"),
)),
_ => None,
}
}
Expand Down

0 comments on commit 24207a2

Please sign in to comment.