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