af_sui_types/
hash.rs

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    /// Input for transactions that interact with this object.
15    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}