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