sui_types/
transfer.rs

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