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 }
29 | ConsensusAddress {
30 start_version: initial_shared_version,
31 ..
32 } => ObjectArg::SharedObject {
33 id,
34 initial_shared_version,
35 mutable,
36 },
37 }
38 }
39}
40
41impl TransactionData {
42 pub fn digest(&self) -> TransactionDigest {
43 const SALT: &str = "TransactionData::";
44 let digest = type_digest(SALT, self);
45 TransactionDigest::new(digest.into_inner())
46 }
47}
48
49fn type_digest<T: serde::Serialize>(salt: &str, ty: &T) -> Digest {
50 let mut hasher = Hasher::new();
51 hasher.update(salt);
52 bcs::serialize_into(&mut hasher, ty).expect("All types used are BCS-compatible");
53 Digest::new(hasher.finalize().into_inner())
54}
55
56impl TransactionData {
57 pub fn signing_digest(&self) -> SigningDigest {
58 const INTENT: Intent = Intent {
59 scope: IntentScope::TransactionData,
60 version: IntentVersion::V0,
61 app_id: IntentAppId::Sui,
62 };
63 let digest = signing_digest(INTENT, self);
64 digest.into_inner()
65 }
66}
67
68fn signing_digest<T: serde::Serialize + ?Sized>(intent: Intent, ty: &T) -> sui_sdk_types::Digest {
69 let mut hasher = Hasher::new();
70 hasher.update(intent.to_bytes());
71 bcs::serialize_into(&mut hasher, ty).expect("T is BCS-compatible");
72 hasher.finalize()
73}