iota_types/
transfer.rs

1// Copyright (c) Mysten Labs, Inc.
2// Modifications Copyright (c) 2024 IOTA Stiftung
3// SPDX-License-Identifier: Apache-2.0
4
5use 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/// Rust version of the Move iota::transfer::Receiving type
31#[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            // TODO: this should really include the type parameters eventually when we add type
55            // parameters to the other polymorphic types like this.
56            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}