1use sui_sdk_types::hash::Hasher;
2use sui_sdk_types::{Intent, IntentAppId, IntentScope, IntentVersion, SigningDigest};
3
4use crate::sui::transaction::ObjectArg;
5use crate::{Digest, Object, ObjectDigest, Owner, TransactionData, TransactionDigest};
6
7impl Object {
8 pub fn digest(&self) -> ObjectDigest {
9 const SALT: &str = "Object::";
10 let digest = type_digest(SALT, self);
11 ObjectDigest::new(digest.into_inner())
12 }
13
14 pub fn object_arg(&self, mutable: bool) -> ObjectArg {
16 use Owner::*;
17 let id = self.id();
18 match self.owner {
19 AddressOwner(_) | ObjectOwner(_) | Immutable => {
20 ObjectArg::ImmOrOwnedObject((id, self.version(), self.digest()))
21 }
22 Shared {
23 initial_shared_version,
24 }
25 | ConsensusV2 {
26 start_version: initial_shared_version,
27 ..
28 } => ObjectArg::SharedObject {
29 id,
30 initial_shared_version,
31 mutable,
32 },
33 }
34 }
35}
36
37impl TransactionData {
38 pub fn digest(&self) -> TransactionDigest {
39 const SALT: &str = "TransactionData::";
40 let digest = type_digest(SALT, self);
41 TransactionDigest::new(digest.into_inner())
42 }
43}
44
45fn type_digest<T: serde::Serialize>(salt: &str, ty: &T) -> Digest {
46 let mut hasher = Hasher::new();
47 hasher.update(salt);
48 bcs::serialize_into(&mut hasher, ty).expect("All types used are BCS-compatible");
49 Digest::new(hasher.finalize().into_inner())
50}
51
52impl TransactionData {
53 pub fn signing_digest(&self) -> SigningDigest {
54 const INTENT: Intent = Intent {
55 scope: IntentScope::TransactionData,
56 version: IntentVersion::V0,
57 app_id: IntentAppId::Sui,
58 };
59 let digest = signing_digest(INTENT, self);
60 digest.into_inner()
61 }
62}
63
64fn signing_digest<T: serde::Serialize + ?Sized>(intent: Intent, ty: &T) -> sui_sdk_types::Digest {
65 let mut hasher = Hasher::new();
66 hasher.update(intent.to_bytes());
67 bcs::serialize_into(&mut hasher, ty).expect("T is BCS-compatible");
68 hasher.finalize()
69}