1use move_binary_format::{CompiledModule, file_format::SignatureToken};
5use move_bytecode_utils::resolve_struct;
6use move_core_types::{
7 account_address::AccountAddress,
8 ident_str,
9 identifier::IdentStr,
10 language_storage::{StructTag, TypeTag},
11};
12use serde::{Deserialize, Serialize};
13
14use crate::{
15 SUI_FRAMEWORK_ADDRESS,
16 base_types::{ObjectID, SequenceNumber},
17 id::ID,
18};
19
20const TRANSFER_MODULE_NAME: &IdentStr = ident_str!("transfer");
21const RECEIVING_STRUCT_NAME: &IdentStr = ident_str!("Receiving");
22
23pub const RESOLVED_RECEIVING_STRUCT: (&AccountAddress, &IdentStr, &IdentStr) = (
24 &SUI_FRAMEWORK_ADDRESS,
25 TRANSFER_MODULE_NAME,
26 RECEIVING_STRUCT_NAME,
27);
28
29#[derive(Clone, Serialize, Deserialize, Debug)]
31pub struct Receiving {
32 pub id: ID,
33 pub version: SequenceNumber,
34}
35
36impl Receiving {
37 pub fn new(id: ObjectID, version: SequenceNumber) -> Self {
38 Self {
39 id: ID::new(id),
40 version,
41 }
42 }
43
44 pub fn to_bcs_bytes(&self) -> Vec<u8> {
45 bcs::to_bytes(self).expect("Value representation is owned and should always serialize")
46 }
47
48 pub fn struct_tag() -> StructTag {
49 StructTag {
50 address: SUI_FRAMEWORK_ADDRESS,
51 module: TRANSFER_MODULE_NAME.to_owned(),
52 name: RECEIVING_STRUCT_NAME.to_owned(),
53 type_params: vec![],
56 }
57 }
58
59 pub fn type_tag() -> TypeTag {
60 TypeTag::Struct(Box::new(Self::struct_tag()))
61 }
62
63 pub fn is_receiving(view: &CompiledModule, s: &SignatureToken) -> bool {
64 use SignatureToken as S;
65 match s {
66 S::MutableReference(inner) | S::Reference(inner) => Self::is_receiving(view, inner),
67 S::DatatypeInstantiation(inst) => {
68 let (idx, type_args) = &**inst;
69 let struct_tag = resolve_struct(view, *idx);
70 struct_tag == RESOLVED_RECEIVING_STRUCT && type_args.len() == 1
71 }
72 _ => false,
73 }
74 }
75}