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